//===-- VEISelDAGToDAG.cpp - A dag to dag inst selector for VE ------------===//
//
// 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 defines an instruction selector for the VE target.
//
//===----------------------------------------------------------------------===//

#include "VE.h"
#include "VETargetMachine.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
using namespace llvm;

#define DEBUG_TYPE "ve-isel"
#define PASS_NAME "VE DAG->DAG Pattern Instruction Selection"

//===--------------------------------------------------------------------===//
/// VEDAGToDAGISel - VE specific code to select VE machine
/// instructions for SelectionDAG operations.
///
namespace {
class VEDAGToDAGISel : public SelectionDAGISel {
  /// Subtarget - Keep a pointer to the VE Subtarget around so that we can
  /// make the right decision when generating code for different targets.
  const VESubtarget *Subtarget;

public:
  VEDAGToDAGISel() = delete;

  explicit VEDAGToDAGISel(VETargetMachine &tm) : SelectionDAGISel(tm) {}

  bool runOnMachineFunction(MachineFunction &MF) override {
    Subtarget = &MF.getSubtarget<VESubtarget>();
    return SelectionDAGISel::runOnMachineFunction(MF);
  }

  void Select(SDNode *N) override;

  // Complex Pattern Selectors.
  bool selectADDRrri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
  bool selectADDRrii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
  bool selectADDRzri(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
  bool selectADDRzii(SDValue N, SDValue &Base, SDValue &Index, SDValue &Offset);
  bool selectADDRri(SDValue N, SDValue &Base, SDValue &Offset);
  bool selectADDRzi(SDValue N, SDValue &Base, SDValue &Offset);

  /// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
  /// inline asm expressions.
  bool SelectInlineAsmMemoryOperand(const SDValue &Op,
                                    InlineAsm::ConstraintCode ConstraintID,
                                    std::vector<SDValue> &OutOps) override;

  // Include the pieces autogenerated from the target description.
#include "VEGenDAGISel.inc"

private:
  SDNode *getGlobalBaseReg();

  bool matchADDRrr(SDValue N, SDValue &Base, SDValue &Index);
  bool matchADDRri(SDValue N, SDValue &Base, SDValue &Offset);
};

class VEDAGToDAGISelLegacy : public SelectionDAGISelLegacy {
public:
  static char ID;
  explicit VEDAGToDAGISelLegacy(VETargetMachine &tm)
      : SelectionDAGISelLegacy(ID, std::make_unique<VEDAGToDAGISel>(tm)) {}
};
} // end anonymous namespace

char VEDAGToDAGISelLegacy::ID = 0;

INITIALIZE_PASS(VEDAGToDAGISelLegacy, DEBUG_TYPE, PASS_NAME, false, false)

bool VEDAGToDAGISel::selectADDRrri(SDValue Addr, SDValue &Base, SDValue &Index,
                                   SDValue &Offset) {
  if (Addr.getOpcode() == ISD::FrameIndex)
    return false;
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress ||
      Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
    return false; // direct calls.

  SDValue LHS, RHS;
  if (matchADDRri(Addr, LHS, RHS)) {
    if (matchADDRrr(LHS, Base, Index)) {
      Offset = RHS;
      return true;
    }
    // Return false to try selectADDRrii.
    return false;
  }
  if (matchADDRrr(Addr, LHS, RHS)) {
    // If the input is a pair of a frame-index and a register, move a
    // frame-index to LHS.  This generates MI with following operands.
    //    %dest, #FI, %reg, offset
    // In the eliminateFrameIndex, above MI is converted to the following.
    //    %dest, %fp, %reg, fi_offset + offset
    if (isa<FrameIndexSDNode>(RHS))
      std::swap(LHS, RHS);

    if (matchADDRri(RHS, Index, Offset)) {
      Base = LHS;
      return true;
    }
    if (matchADDRri(LHS, Base, Offset)) {
      Index = RHS;
      return true;
    }
    Base = LHS;
    Index = RHS;
    Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
    return true;
  }
  return false; // Let the reg+imm(=0) pattern catch this!
}

bool VEDAGToDAGISel::selectADDRrii(SDValue Addr, SDValue &Base, SDValue &Index,
                                   SDValue &Offset) {
  if (matchADDRri(Addr, Base, Offset)) {
    Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
    return true;
  }

  Base = Addr;
  Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
  return true;
}

bool VEDAGToDAGISel::selectADDRzri(SDValue Addr, SDValue &Base, SDValue &Index,
                                   SDValue &Offset) {
  // Prefer ADDRrii.
  return false;
}

bool VEDAGToDAGISel::selectADDRzii(SDValue Addr, SDValue &Base, SDValue &Index,
                                   SDValue &Offset) {
  if (isa<FrameIndexSDNode>(Addr))
    return false;
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress ||
      Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
    return false; // direct calls.

  if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
    if (isInt<32>(CN->getSExtValue())) {
      Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
      Index = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
      Offset =
          CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
      return true;
    }
  }
  return false;
}

bool VEDAGToDAGISel::selectADDRri(SDValue Addr, SDValue &Base,
                                  SDValue &Offset) {
  if (matchADDRri(Addr, Base, Offset))
    return true;

  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
  return true;
}

bool VEDAGToDAGISel::selectADDRzi(SDValue Addr, SDValue &Base,
                                  SDValue &Offset) {
  if (isa<FrameIndexSDNode>(Addr))
    return false;
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress ||
      Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
    return false; // direct calls.

  if (auto *CN = dyn_cast<ConstantSDNode>(Addr)) {
    if (isInt<32>(CN->getSExtValue())) {
      Base = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
      Offset =
          CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
      return true;
    }
  }
  return false;
}

bool VEDAGToDAGISel::matchADDRrr(SDValue Addr, SDValue &Base, SDValue &Index) {
  if (isa<FrameIndexSDNode>(Addr))
    return false;
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress ||
      Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
    return false; // direct calls.

  if (Addr.getOpcode() == ISD::ADD) {
    ; // Nothing to do here.
  } else if (Addr.getOpcode() == ISD::OR) {
    // We want to look through a transform in InstCombine and DAGCombiner that
    // turns 'add' into 'or', so we can treat this 'or' exactly like an 'add'.
    if (!CurDAG->haveNoCommonBitsSet(Addr.getOperand(0), Addr.getOperand(1)))
      return false;
  } else {
    return false;
  }

  if (Addr.getOperand(0).getOpcode() == VEISD::Lo ||
      Addr.getOperand(1).getOpcode() == VEISD::Lo)
    return false; // Let the LEASL patterns catch this!

  Base = Addr.getOperand(0);
  Index = Addr.getOperand(1);
  return true;
}

bool VEDAGToDAGISel::matchADDRri(SDValue Addr, SDValue &Base, SDValue &Offset) {
  auto AddrTy = Addr->getValueType(0);
  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
    Offset = CurDAG->getTargetConstant(0, SDLoc(Addr), MVT::i32);
    return true;
  }
  if (Addr.getOpcode() == ISD::TargetExternalSymbol ||
      Addr.getOpcode() == ISD::TargetGlobalAddress ||
      Addr.getOpcode() == ISD::TargetGlobalTLSAddress)
    return false; // direct calls.

  if (CurDAG->isBaseWithConstantOffset(Addr)) {
    ConstantSDNode *CN = cast<ConstantSDNode>(Addr.getOperand(1));
    if (isInt<32>(CN->getSExtValue())) {
      if (FrameIndexSDNode *FIN =
              dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
        // Constant offset from frame ref.
        Base = CurDAG->getTargetFrameIndex(FIN->getIndex(), AddrTy);
      } else {
        Base = Addr.getOperand(0);
      }
      Offset =
          CurDAG->getTargetConstant(CN->getZExtValue(), SDLoc(Addr), MVT::i32);
      return true;
    }
  }
  return false;
}

void VEDAGToDAGISel::Select(SDNode *N) {
  SDLoc dl(N);
  if (N->isMachineOpcode()) {
    N->setNodeId(-1);
    return; // Already selected.
  }

  switch (N->getOpcode()) {

  // Late eliminate the LEGALAVL wrapper
  case VEISD::LEGALAVL:
    ReplaceNode(N, N->getOperand(0).getNode());
    return;

  // Lower (broadcast 1) and (broadcast 0) to VM[P]0
  case VEISD::VEC_BROADCAST: {
    MVT SplatResTy = N->getSimpleValueType(0);
    if (SplatResTy.getVectorElementType() != MVT::i1)
      break;

    // Constant non-zero broadcast.
    auto BConst = dyn_cast<ConstantSDNode>(N->getOperand(0));
    if (!BConst)
      break;
    bool BCTrueMask = (BConst->getSExtValue() != 0);
    if (!BCTrueMask)
      break;

    // Packed or non-packed.
    SDValue New;
    if (SplatResTy.getVectorNumElements() == StandardVectorWidth) {
      New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VM0,
                                   MVT::v256i1);
    } else if (SplatResTy.getVectorNumElements() == PackedVectorWidth) {
      New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(), SDLoc(N), VE::VMP0,
                                   MVT::v512i1);
    } else
      break;

    // Replace.
    ReplaceNode(N, New.getNode());
    return;
  }

  case VEISD::GLOBAL_BASE_REG:
    ReplaceNode(N, getGlobalBaseReg());
    return;
  }

  SelectCode(N);
}

/// SelectInlineAsmMemoryOperand - Implement addressing mode selection for
/// inline asm expressions.
bool VEDAGToDAGISel::SelectInlineAsmMemoryOperand(
    const SDValue &Op, InlineAsm::ConstraintCode ConstraintID,
    std::vector<SDValue> &OutOps) {
  SDValue Op0, Op1;
  switch (ConstraintID) {
  default:
    llvm_unreachable("Unexpected asm memory constraint");
  case InlineAsm::ConstraintCode::o:
  case InlineAsm::ConstraintCode::m: // memory
    // Try to match ADDRri since reg+imm style is safe for all VE instructions
    // with a memory operand.
    if (selectADDRri(Op, Op0, Op1)) {
      OutOps.push_back(Op0);
      OutOps.push_back(Op1);
      return false;
    }
    // Otherwise, require the address to be in a register and immediate 0.
    OutOps.push_back(Op);
    OutOps.push_back(CurDAG->getTargetConstant(0, SDLoc(Op), MVT::i32));
    return false;
  }
  return true;
}

SDNode *VEDAGToDAGISel::getGlobalBaseReg() {
  Register GlobalBaseReg = Subtarget->getInstrInfo()->getGlobalBaseReg(MF);
  return CurDAG
      ->getRegister(GlobalBaseReg, TLI->getPointerTy(CurDAG->getDataLayout()))
      .getNode();
}

/// createVEISelDag - This pass converts a legalized DAG into a
/// VE-specific DAG, ready for instruction scheduling.
///
FunctionPass *llvm::createVEISelDag(VETargetMachine &TM) {
  return new VEDAGToDAGISelLegacy(TM);
}
