//=== HexagonSplitConst32AndConst64.cpp - split CONST32/Const64 into HI/LO ===//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// When the compiler is invoked with no small data, for instance, with the -G0
// command line option, then all CONST* opcodes should be broken down into
// appropriate LO and HI instructions. This splitting is done by this pass.
// The only reason this is not done in the DAG lowering itself is that there
// is no simple way of getting the register allocator to allot the same hard
// register to the result of LO and HI instructions. This pass is always
// scheduled after register allocation.
//
//===----------------------------------------------------------------------===//

#include "HexagonSubtarget.h"
#include "HexagonTargetMachine.h"
#include "HexagonTargetObjectFile.h"
#include "llvm/CodeGen/MachineFunctionPass.h"
#include "llvm/CodeGen/MachineInstrBuilder.h"
#include "llvm/CodeGen/Passes.h"
#include "llvm/Target/TargetInstrInfo.h"
#include "llvm/Target/TargetRegisterInfo.h"

using namespace llvm;

#define DEBUG_TYPE "xfer"

namespace llvm {
  FunctionPass *createHexagonSplitConst32AndConst64();
  void initializeHexagonSplitConst32AndConst64Pass(PassRegistry&);
}

namespace {
  class HexagonSplitConst32AndConst64 : public MachineFunctionPass {
  public:
    static char ID;
    HexagonSplitConst32AndConst64() : MachineFunctionPass(ID) {
      PassRegistry &R = *PassRegistry::getPassRegistry();
      initializeHexagonSplitConst32AndConst64Pass(R);
    }
    StringRef getPassName() const override {
      return "Hexagon Split Const32s and Const64s";
    }
    bool runOnMachineFunction(MachineFunction &Fn) override;
    MachineFunctionProperties getRequiredProperties() const override {
      return MachineFunctionProperties().set(
          MachineFunctionProperties::Property::NoVRegs);
    }
  };
}

char HexagonSplitConst32AndConst64::ID = 0;

INITIALIZE_PASS(HexagonSplitConst32AndConst64, "split-const-for-sdata",
      "Hexagon Split Const32s and Const64s", false, false)

bool HexagonSplitConst32AndConst64::runOnMachineFunction(MachineFunction &Fn) {
  const HexagonTargetObjectFile &TLOF =
      *static_cast<const HexagonTargetObjectFile *>(
          Fn.getTarget().getObjFileLowering());
  if (TLOF.isSmallDataEnabled())
    return true;

  const TargetInstrInfo *TII = Fn.getSubtarget().getInstrInfo();
  const TargetRegisterInfo *TRI = Fn.getSubtarget().getRegisterInfo();

  // Loop over all of the basic blocks
  for (MachineBasicBlock &B : Fn) {
    for (auto I = B.begin(), E = B.end(); I != E; ) {
      MachineInstr &MI = *I;
      ++I;
      unsigned Opc = MI.getOpcode();

      if (Opc == Hexagon::CONST32) {
        unsigned DestReg = MI.getOperand(0).getReg();
        uint64_t ImmValue = MI.getOperand(1).getImm();
        const DebugLoc &DL = MI.getDebugLoc();
        BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestReg)
            .addImm(ImmValue);
        B.erase(&MI);
      } else if (Opc == Hexagon::CONST64) {
        unsigned DestReg = MI.getOperand(0).getReg();
        int64_t ImmValue = MI.getOperand(1).getImm();
        const DebugLoc &DL = MI.getDebugLoc();
        unsigned DestLo = TRI->getSubReg(DestReg, Hexagon::isub_lo);
        unsigned DestHi = TRI->getSubReg(DestReg, Hexagon::isub_hi);

        int32_t LowWord = (ImmValue & 0xFFFFFFFF);
        int32_t HighWord = (ImmValue >> 32) & 0xFFFFFFFF;

        BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestLo)
            .addImm(LowWord);
        BuildMI(B, MI, DL, TII->get(Hexagon::A2_tfrsi), DestHi)
            .addImm(HighWord);
        B.erase(&MI);
      }
    }
  }

  return true;
}


//===----------------------------------------------------------------------===//
//                         Public Constructor Functions
//===----------------------------------------------------------------------===//

FunctionPass *llvm::createHexagonSplitConst32AndConst64() {
  return new HexagonSplitConst32AndConst64();
}
