//===-- LanaiISelDAGToDAG.cpp - A dag to dag inst selector for Lanai ------===//
//
// 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 Lanai target.
//
//===----------------------------------------------------------------------===//

#include "LanaiAluCode.h"
#include "LanaiMachineFunctionInfo.h"
#include "LanaiRegisterInfo.h"
#include "LanaiSubtarget.h"
#include "LanaiTargetMachine.h"
#include "llvm/CodeGen/MachineConstantPool.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/CodeGen/MachineFunction.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/MachineRegisterInfo.h"
#include "llvm/CodeGen/SelectionDAGISel.h"
#include "llvm/IR/CFG.h"
#include "llvm/IR/GlobalValue.h"
#include "llvm/IR/Instructions.h"
#include "llvm/IR/Intrinsics.h"
#include "llvm/IR/Type.h"
#include "llvm/Support/Debug.h"
#include "llvm/Support/ErrorHandling.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/Target/TargetMachine.h"

using namespace llvm;

#define DEBUG_TYPE "lanai-isel"
#define PASS_NAME "Lanai DAG->DAG Pattern Instruction Selection"

//===----------------------------------------------------------------------===//
// Instruction Selector Implementation
//===----------------------------------------------------------------------===//

//===----------------------------------------------------------------------===//
// LanaiDAGToDAGISel - Lanai specific code to select Lanai machine
// instructions for SelectionDAG operations.
//===----------------------------------------------------------------------===//
namespace {

class LanaiDAGToDAGISel : public SelectionDAGISel {
public:
  static char ID;

  LanaiDAGToDAGISel() = delete;

  explicit LanaiDAGToDAGISel(LanaiTargetMachine &TargetMachine)
      : SelectionDAGISel(ID, TargetMachine) {}

  bool runOnMachineFunction(MachineFunction &MF) override {
    return SelectionDAGISel::runOnMachineFunction(MF);
  }

  bool SelectInlineAsmMemoryOperand(const SDValue &Op, unsigned ConstraintCode,
                                    std::vector<SDValue> &OutOps) override;

private:
// Include the pieces autogenerated from the target description.
#include "LanaiGenDAGISel.inc"

  // Instruction Selection not handled by the auto-generated tablgen
  void Select(SDNode *N) override;

  // Support functions for the opcodes of Instruction Selection
  // not handled by the auto-generated tablgen
  void selectFrameIndex(SDNode *N);

  // Complex Pattern for address selection.
  bool selectAddrRi(SDValue Addr, SDValue &Base, SDValue &Offset,
                    SDValue &AluOp);
  bool selectAddrRr(SDValue Addr, SDValue &R1, SDValue &R2, SDValue &AluOp);
  bool selectAddrSls(SDValue Addr, SDValue &Offset);
  bool selectAddrSpls(SDValue Addr, SDValue &Base, SDValue &Offset,
                      SDValue &AluOp);

  // getI32Imm - Return a target constant with the specified value, of type i32.
  inline SDValue getI32Imm(unsigned Imm, const SDLoc &DL) {
    return CurDAG->getTargetConstant(Imm, DL, MVT::i32);
  }

private:
  bool selectAddrRiSpls(SDValue Addr, SDValue &Base, SDValue &Offset,
                        SDValue &AluOp, bool RiMode);
};

bool canBeRepresentedAsSls(const ConstantSDNode &CN) {
  // Fits in 21-bit signed immediate and two low-order bits are zero.
  return isInt<21>(CN.getSExtValue()) && ((CN.getSExtValue() & 0x3) == 0);
}

} // namespace

char LanaiDAGToDAGISel::ID = 0;

INITIALIZE_PASS(LanaiDAGToDAGISel, DEBUG_TYPE, PASS_NAME, false, false)

// Helper functions for ComplexPattern used on LanaiInstrInfo
// Used on Lanai Load/Store instructions.
bool LanaiDAGToDAGISel::selectAddrSls(SDValue Addr, SDValue &Offset) {
  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr)) {
    SDLoc DL(Addr);
    // Loading from a constant address.
    if (canBeRepresentedAsSls(*CN)) {
      int32_t Imm = CN->getSExtValue();
      Offset = CurDAG->getTargetConstant(Imm, DL, CN->getValueType(0));
      return true;
    }
  }
  if (Addr.getOpcode() == ISD::OR &&
      Addr.getOperand(1).getOpcode() == LanaiISD::SMALL) {
    Offset = Addr.getOperand(1).getOperand(0);
    return true;
  }
  return false;
}

bool LanaiDAGToDAGISel::selectAddrRiSpls(SDValue Addr, SDValue &Base,
                                         SDValue &Offset, SDValue &AluOp,
                                         bool RiMode) {
  SDLoc DL(Addr);

  if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr)) {
    if (RiMode) {
      // Fits in 16-bit signed immediate.
      if (isInt<16>(CN->getSExtValue())) {
        int16_t Imm = CN->getSExtValue();
        Offset = CurDAG->getTargetConstant(Imm, DL, CN->getValueType(0));
        Base = CurDAG->getRegister(Lanai::R0, CN->getValueType(0));
        AluOp = CurDAG->getTargetConstant(LPAC::ADD, DL, MVT::i32);
        return true;
      }
      // Allow SLS to match if the constant doesn't fit in 16 bits but can be
      // represented as an SLS.
      if (canBeRepresentedAsSls(*CN))
        return false;
    } else {
      // Fits in 10-bit signed immediate.
      if (isInt<10>(CN->getSExtValue())) {
        int16_t Imm = CN->getSExtValue();
        Offset = CurDAG->getTargetConstant(Imm, DL, CN->getValueType(0));
        Base = CurDAG->getRegister(Lanai::R0, CN->getValueType(0));
        AluOp = CurDAG->getTargetConstant(LPAC::ADD, DL, MVT::i32);
        return true;
      }
    }
  }

  // if Address is FI, get the TargetFrameIndex.
  if (FrameIndexSDNode *FIN = dyn_cast<FrameIndexSDNode>(Addr)) {
    Base = CurDAG->getTargetFrameIndex(
        FIN->getIndex(),
        getTargetLowering()->getPointerTy(CurDAG->getDataLayout()));
    Offset = CurDAG->getTargetConstant(0, DL, MVT::i32);
    AluOp = CurDAG->getTargetConstant(LPAC::ADD, DL, MVT::i32);
    return true;
  }

  // Skip direct calls
  if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
       Addr.getOpcode() == ISD::TargetGlobalAddress))
    return false;

  // Address of the form imm + reg
  ISD::NodeType AluOperator = static_cast<ISD::NodeType>(Addr.getOpcode());
  if (AluOperator == ISD::ADD) {
    AluOp = CurDAG->getTargetConstant(LPAC::ADD, DL, MVT::i32);
    // Addresses of the form FI+const
    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
      if ((RiMode && isInt<16>(CN->getSExtValue())) ||
          (!RiMode && isInt<10>(CN->getSExtValue()))) {
        // If the first operand is a FI, get the TargetFI Node
        if (FrameIndexSDNode *FIN =
                dyn_cast<FrameIndexSDNode>(Addr.getOperand(0))) {
          Base = CurDAG->getTargetFrameIndex(
              FIN->getIndex(),
              getTargetLowering()->getPointerTy(CurDAG->getDataLayout()));
        } else {
          Base = Addr.getOperand(0);
        }

        Offset = CurDAG->getTargetConstant(CN->getSExtValue(), DL, MVT::i32);
        return true;
      }
  }

  // Let SLS match SMALL instead of RI.
  if (AluOperator == ISD::OR && RiMode &&
      Addr.getOperand(1).getOpcode() == LanaiISD::SMALL)
    return false;

  Base = Addr;
  Offset = CurDAG->getTargetConstant(0, DL, MVT::i32);
  AluOp = CurDAG->getTargetConstant(LPAC::ADD, DL, MVT::i32);
  return true;
}

bool LanaiDAGToDAGISel::selectAddrRi(SDValue Addr, SDValue &Base,
                                     SDValue &Offset, SDValue &AluOp) {
  return selectAddrRiSpls(Addr, Base, Offset, AluOp, /*RiMode=*/true);
}

bool LanaiDAGToDAGISel::selectAddrSpls(SDValue Addr, SDValue &Base,
                                       SDValue &Offset, SDValue &AluOp) {
  return selectAddrRiSpls(Addr, Base, Offset, AluOp, /*RiMode=*/false);
}

bool LanaiDAGToDAGISel::selectAddrRr(SDValue Addr, SDValue &R1, SDValue &R2,
                                     SDValue &AluOp) {
  // if Address is FI, get the TargetFrameIndex.
  if (Addr.getOpcode() == ISD::FrameIndex)
    return false;

  // Skip direct calls
  if ((Addr.getOpcode() == ISD::TargetExternalSymbol ||
       Addr.getOpcode() == ISD::TargetGlobalAddress))
    return false;

  // Address of the form OP + OP
  ISD::NodeType AluOperator = static_cast<ISD::NodeType>(Addr.getOpcode());
  LPAC::AluCode AluCode = LPAC::isdToLanaiAluCode(AluOperator);
  if (AluCode != LPAC::UNKNOWN) {
    // Skip addresses of the form FI OP const
    if (ConstantSDNode *CN = dyn_cast<ConstantSDNode>(Addr.getOperand(1)))
      if (isInt<16>(CN->getSExtValue()))
        return false;

    // Skip addresses with hi/lo operands
    if (Addr.getOperand(0).getOpcode() == LanaiISD::HI ||
        Addr.getOperand(0).getOpcode() == LanaiISD::LO ||
        Addr.getOperand(0).getOpcode() == LanaiISD::SMALL ||
        Addr.getOperand(1).getOpcode() == LanaiISD::HI ||
        Addr.getOperand(1).getOpcode() == LanaiISD::LO ||
        Addr.getOperand(1).getOpcode() == LanaiISD::SMALL)
      return false;

    // Addresses of the form register OP register
    R1 = Addr.getOperand(0);
    R2 = Addr.getOperand(1);
    AluOp = CurDAG->getTargetConstant(AluCode, SDLoc(Addr), MVT::i32);
    return true;
  }

  // Skip addresses with zero offset
  return false;
}

bool LanaiDAGToDAGISel::SelectInlineAsmMemoryOperand(
    const SDValue &Op, unsigned ConstraintCode, std::vector<SDValue> &OutOps) {
  SDValue Op0, Op1, AluOp;
  switch (ConstraintCode) {
  default:
    return true;
  case InlineAsm::Constraint_m: // memory
    if (!selectAddrRr(Op, Op0, Op1, AluOp) &&
        !selectAddrRi(Op, Op0, Op1, AluOp))
      return true;
    break;
  }

  OutOps.push_back(Op0);
  OutOps.push_back(Op1);
  OutOps.push_back(AluOp);
  return false;
}

// Select instructions not customized! Used for
// expanded, promoted and normal instructions
void LanaiDAGToDAGISel::Select(SDNode *Node) {
  unsigned Opcode = Node->getOpcode();

  // If we have a custom node, we already have selected!
  if (Node->isMachineOpcode()) {
    LLVM_DEBUG(errs() << "== "; Node->dump(CurDAG); errs() << "\n");
    return;
  }

  // Instruction Selection not handled by the auto-generated tablegen selection
  // should be handled here.
  EVT VT = Node->getValueType(0);
  switch (Opcode) {
  case ISD::Constant:
    if (VT == MVT::i32) {
      ConstantSDNode *ConstNode = cast<ConstantSDNode>(Node);
      // Materialize zero constants as copies from R0. This allows the coalescer
      // to propagate these into other instructions.
      if (ConstNode->isZero()) {
        SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
                                             SDLoc(Node), Lanai::R0, MVT::i32);
        return ReplaceNode(Node, New.getNode());
      }
      // Materialize all ones constants as copies from R1. This allows the
      // coalescer to propagate these into other instructions.
      if (ConstNode->isAllOnes()) {
        SDValue New = CurDAG->getCopyFromReg(CurDAG->getEntryNode(),
                                             SDLoc(Node), Lanai::R1, MVT::i32);
        return ReplaceNode(Node, New.getNode());
      }
    }
    break;
  case ISD::FrameIndex:
    selectFrameIndex(Node);
    return;
  default:
    break;
  }

  // Select the default instruction
  SelectCode(Node);
}

void LanaiDAGToDAGISel::selectFrameIndex(SDNode *Node) {
  SDLoc DL(Node);
  SDValue Imm = CurDAG->getTargetConstant(0, DL, MVT::i32);
  int FI = cast<FrameIndexSDNode>(Node)->getIndex();
  EVT VT = Node->getValueType(0);
  SDValue TFI = CurDAG->getTargetFrameIndex(FI, VT);
  unsigned Opc = Lanai::ADD_I_LO;
  if (Node->hasOneUse()) {
    CurDAG->SelectNodeTo(Node, Opc, VT, TFI, Imm);
    return;
  }
  ReplaceNode(Node, CurDAG->getMachineNode(Opc, DL, VT, TFI, Imm));
}

// createLanaiISelDag - This pass converts a legalized DAG into a
// Lanai-specific DAG, ready for instruction scheduling.
FunctionPass *llvm::createLanaiISelDag(LanaiTargetMachine &TM) {
  return new LanaiDAGToDAGISel(TM);
}
