//===-- 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"

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

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

class LanaiDAGToDAGISel : public SelectionDAGISel {
public:
  explicit LanaiDAGToDAGISel(LanaiTargetMachine &TargetMachine)
      : SelectionDAGISel(TargetMachine) {}

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

  // Pass Name
  StringRef getPassName() const override {
    return "Lanai DAG->DAG Pattern Instruction Selection";
  }

  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

// 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->isNullValue()) {
        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->isAllOnesValue()) {
        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);
}
