//===-- CSKYInstrInfo.h - CSKY Instruction Information --------*- C++ -*---===//
//
// 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 contains the CSKY implementation of the TargetInstrInfo class.
//
//===----------------------------------------------------------------------===//

#include "CSKYInstrInfo.h"
#include "CSKYConstantPoolValue.h"
#include "CSKYMachineFunctionInfo.h"
#include "CSKYTargetMachine.h"
#include "llvm/CodeGen/MachineFrameInfo.h"
#include "llvm/MC/MCContext.h"

#define DEBUG_TYPE "csky-instr-info"

using namespace llvm;

#define GET_INSTRINFO_CTOR_DTOR
#include "CSKYGenInstrInfo.inc"

CSKYInstrInfo::CSKYInstrInfo(CSKYSubtarget &STI)
    : CSKYGenInstrInfo(CSKY::ADJCALLSTACKDOWN, CSKY::ADJCALLSTACKUP), STI(STI) {
  v2sf = STI.hasFPUv2SingleFloat();
  v2df = STI.hasFPUv2DoubleFloat();
  v3sf = STI.hasFPUv3SingleFloat();
  v3df = STI.hasFPUv3DoubleFloat();
}

static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target,
                            SmallVectorImpl<MachineOperand> &Cond) {
  // Block ends with fall-through condbranch.
  assert(LastInst.getDesc().isConditionalBranch() &&
         "Unknown conditional branch");
  Target = LastInst.getOperand(1).getMBB();
  Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
  Cond.push_back(LastInst.getOperand(0));
}

bool CSKYInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
                                  MachineBasicBlock *&TBB,
                                  MachineBasicBlock *&FBB,
                                  SmallVectorImpl<MachineOperand> &Cond,
                                  bool AllowModify) const {
  TBB = FBB = nullptr;
  Cond.clear();

  // If the block has no terminators, it just falls into the block after it.
  MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
  if (I == MBB.end() || !isUnpredicatedTerminator(*I))
    return false;

  // Count the number of terminators and find the first unconditional or
  // indirect branch.
  MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
  int NumTerminators = 0;
  for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
       J++) {
    NumTerminators++;
    if (J->getDesc().isUnconditionalBranch() ||
        J->getDesc().isIndirectBranch()) {
      FirstUncondOrIndirectBr = J.getReverse();
    }
  }

  // If AllowModify is true, we can erase any terminators after
  // FirstUncondOrIndirectBR.
  if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
    while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
      std::next(FirstUncondOrIndirectBr)->eraseFromParent();
      NumTerminators--;
    }
    I = FirstUncondOrIndirectBr;
  }

  // We can't handle blocks that end in an indirect branch.
  if (I->getDesc().isIndirectBranch())
    return true;

  // We can't handle blocks with more than 2 terminators.
  if (NumTerminators > 2)
    return true;

  // Handle a single unconditional branch.
  if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
    TBB = getBranchDestBlock(*I);
    return false;
  }

  // Handle a single conditional branch.
  if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
    parseCondBranch(*I, TBB, Cond);
    return false;
  }

  // Handle a conditional branch followed by an unconditional branch.
  if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
      I->getDesc().isUnconditionalBranch()) {
    parseCondBranch(*std::prev(I), TBB, Cond);
    FBB = getBranchDestBlock(*I);
    return false;
  }

  // Otherwise, we can't handle this.
  return true;
}

unsigned CSKYInstrInfo::removeBranch(MachineBasicBlock &MBB,
                                     int *BytesRemoved) const {
  if (BytesRemoved)
    *BytesRemoved = 0;
  MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
  if (I == MBB.end())
    return 0;

  if (!I->getDesc().isUnconditionalBranch() &&
      !I->getDesc().isConditionalBranch())
    return 0;

  // Remove the branch.
  if (BytesRemoved)
    *BytesRemoved += getInstSizeInBytes(*I);
  I->eraseFromParent();

  I = MBB.end();

  if (I == MBB.begin())
    return 1;
  --I;
  if (!I->getDesc().isConditionalBranch())
    return 1;

  // Remove the branch.
  if (BytesRemoved)
    *BytesRemoved += getInstSizeInBytes(*I);
  I->eraseFromParent();
  return 2;
}

MachineBasicBlock *
CSKYInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
  assert(MI.getDesc().isBranch() && "Unexpected opcode!");
  // The branch target is always the last operand.
  int NumOp = MI.getNumExplicitOperands();
  assert(MI.getOperand(NumOp - 1).isMBB() && "Expected MBB!");
  return MI.getOperand(NumOp - 1).getMBB();
}

unsigned CSKYInstrInfo::insertBranch(
    MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
    ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
  if (BytesAdded)
    *BytesAdded = 0;

  // Shouldn't be a fall through.
  assert(TBB && "insertBranch must not be told to insert a fallthrough");
  assert((Cond.size() == 2 || Cond.size() == 0) &&
         "CSKY branch conditions have two components!");

  // Unconditional branch.
  if (Cond.empty()) {
    MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(TBB);
    if (BytesAdded)
      *BytesAdded += getInstSizeInBytes(MI);
    return 1;
  }

  // Either a one or two-way conditional branch.
  unsigned Opc = Cond[0].getImm();
  MachineInstr &CondMI = *BuildMI(&MBB, DL, get(Opc)).add(Cond[1]).addMBB(TBB);
  if (BytesAdded)
    *BytesAdded += getInstSizeInBytes(CondMI);

  // One-way conditional branch.
  if (!FBB)
    return 1;

  // Two-way conditional branch.
  MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(FBB);
  if (BytesAdded)
    *BytesAdded += getInstSizeInBytes(MI);
  return 2;
}

static unsigned getOppositeBranchOpc(unsigned Opcode) {
  switch (Opcode) {
  default:
    llvm_unreachable("Unknown conditional branch!");
  case CSKY::BT32:
    return CSKY::BF32;
  case CSKY::BT16:
    return CSKY::BF16;
  case CSKY::BF32:
    return CSKY::BT32;
  case CSKY::BF16:
    return CSKY::BT16;
  case CSKY::BHZ32:
    return CSKY::BLSZ32;
  case CSKY::BHSZ32:
    return CSKY::BLZ32;
  case CSKY::BLZ32:
    return CSKY::BHSZ32;
  case CSKY::BLSZ32:
    return CSKY::BHZ32;
  case CSKY::BNEZ32:
    return CSKY::BEZ32;
  case CSKY::BEZ32:
    return CSKY::BNEZ32;
  }
}

bool CSKYInstrInfo::reverseBranchCondition(
    SmallVectorImpl<MachineOperand> &Cond) const {
  assert((Cond.size() == 2) && "Invalid branch condition!");
  Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm()));
  return false;
}

Register CSKYInstrInfo::movImm(MachineBasicBlock &MBB,
                               MachineBasicBlock::iterator MBBI,
                               const DebugLoc &DL, uint64_t Val,
                               MachineInstr::MIFlag Flag) const {
  if (!isInt<32>(Val))
    report_fatal_error("Should only materialize 32-bit constants.");

  MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();

  Register DstReg;
  if (STI.hasE2()) {
    DstReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);

    if (isUInt<16>(Val)) {
      BuildMI(MBB, MBBI, DL, get(CSKY::MOVI32), DstReg)
          .addImm(Val & 0xFFFF)
          .setMIFlags(Flag);
    } else if (isShiftedUInt<16, 16>(Val)) {
      BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg)
          .addImm((Val >> 16) & 0xFFFF)
          .setMIFlags(Flag);
    } else {
      BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg)
          .addImm((Val >> 16) & 0xFFFF)
          .setMIFlags(Flag);
      BuildMI(MBB, MBBI, DL, get(CSKY::ORI32), DstReg)
          .addReg(DstReg)
          .addImm(Val & 0xFFFF)
          .setMIFlags(Flag);
    }

  } else {
    DstReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass);
    if (isUInt<8>(Val)) {
      BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
          .addImm(Val & 0xFF)
          .setMIFlags(Flag);
    } else if (isUInt<16>(Val)) {
      BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
          .addImm((Val >> 8) & 0xFF)
          .setMIFlags(Flag);
      BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
          .addReg(DstReg)
          .addImm(8)
          .setMIFlags(Flag);
      if ((Val & 0xFF) != 0)
        BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
            .addReg(DstReg)
            .addImm(Val & 0xFF)
            .setMIFlags(Flag);
    } else if (isUInt<24>(Val)) {
      BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
          .addImm((Val >> 16) & 0xFF)
          .setMIFlags(Flag);
      BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
          .addReg(DstReg)
          .addImm(8)
          .setMIFlags(Flag);
      if (((Val >> 8) & 0xFF) != 0)
        BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
            .addReg(DstReg)
            .addImm((Val >> 8) & 0xFF)
            .setMIFlags(Flag);
      BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
          .addReg(DstReg)
          .addImm(8)
          .setMIFlags(Flag);
      if ((Val & 0xFF) != 0)
        BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
            .addReg(DstReg)
            .addImm(Val & 0xFF)
            .setMIFlags(Flag);
    } else {
      BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
          .addImm((Val >> 24) & 0xFF)
          .setMIFlags(Flag);
      BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
          .addReg(DstReg)
          .addImm(8)
          .setMIFlags(Flag);
      if (((Val >> 16) & 0xFF) != 0)
        BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
            .addReg(DstReg)
            .addImm((Val >> 16) & 0xFF)
            .setMIFlags(Flag);
      BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
          .addReg(DstReg)
          .addImm(8)
          .setMIFlags(Flag);
      if (((Val >> 8) & 0xFF) != 0)
        BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
            .addReg(DstReg)
            .addImm((Val >> 8) & 0xFF)
            .setMIFlags(Flag);
      BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
          .addReg(DstReg)
          .addImm(8)
          .setMIFlags(Flag);
      if ((Val & 0xFF) != 0)
        BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
            .addReg(DstReg)
            .addImm(Val & 0xFF)
            .setMIFlags(Flag);
    }
  }

  return DstReg;
}

Register CSKYInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
                                            int &FrameIndex) const {
  switch (MI.getOpcode()) {
  default:
    return 0;
  case CSKY::LD16B:
  case CSKY::LD16H:
  case CSKY::LD16W:
  case CSKY::LD32B:
  case CSKY::LD32BS:
  case CSKY::LD32H:
  case CSKY::LD32HS:
  case CSKY::LD32W:
  case CSKY::FLD_S:
  case CSKY::FLD_D:
  case CSKY::f2FLD_S:
  case CSKY::f2FLD_D:
  case CSKY::RESTORE_CARRY:
    break;
  }

  if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
      MI.getOperand(2).getImm() == 0) {
    FrameIndex = MI.getOperand(1).getIndex();
    return MI.getOperand(0).getReg();
  }

  return 0;
}

Register CSKYInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
                                           int &FrameIndex) const {
  switch (MI.getOpcode()) {
  default:
    return 0;
  case CSKY::ST16B:
  case CSKY::ST16H:
  case CSKY::ST16W:
  case CSKY::ST32B:
  case CSKY::ST32H:
  case CSKY::ST32W:
  case CSKY::FST_S:
  case CSKY::FST_D:
  case CSKY::f2FST_S:
  case CSKY::f2FST_D:
  case CSKY::SPILL_CARRY:
    break;
  }

  if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
      MI.getOperand(2).getImm() == 0) {
    FrameIndex = MI.getOperand(1).getIndex();
    return MI.getOperand(0).getReg();
  }

  return 0;
}

void CSKYInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
                                        MachineBasicBlock::iterator I,
                                        Register SrcReg, bool IsKill, int FI,
                                        const TargetRegisterClass *RC,
                                        const TargetRegisterInfo *TRI,
                                        Register VReg,
                                        MachineInstr::MIFlag Flags) const {
  DebugLoc DL;
  if (I != MBB.end())
    DL = I->getDebugLoc();

  MachineFunction &MF = *MBB.getParent();
  CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
  MachineFrameInfo &MFI = MF.getFrameInfo();

  unsigned Opcode = 0;

  if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
    Opcode = CSKY::ST32W; // Optimize for 16bit
  } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
    Opcode = CSKY::SPILL_CARRY;
    CFI->setSpillsCR();
  } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
    Opcode = CSKY::FST_S;
  else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
    Opcode = CSKY::FST_D;
  else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
    Opcode = CSKY::f2FST_S;
  else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
    Opcode = CSKY::f2FST_D;
  else {
    llvm_unreachable("Unknown RegisterClass");
  }

  MachineMemOperand *MMO = MF.getMachineMemOperand(
      MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
      MFI.getObjectSize(FI), MFI.getObjectAlign(FI));

  BuildMI(MBB, I, DL, get(Opcode))
      .addReg(SrcReg, getKillRegState(IsKill))
      .addFrameIndex(FI)
      .addImm(0)
      .addMemOperand(MMO);
}

void CSKYInstrInfo::loadRegFromStackSlot(
    MachineBasicBlock &MBB, MachineBasicBlock::iterator I, Register DestReg,
    int FI, const TargetRegisterClass *RC, const TargetRegisterInfo *TRI,
    Register VReg, MachineInstr::MIFlag Flags) const {
  DebugLoc DL;
  if (I != MBB.end())
    DL = I->getDebugLoc();

  MachineFunction &MF = *MBB.getParent();
  CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
  MachineFrameInfo &MFI = MF.getFrameInfo();

  unsigned Opcode = 0;

  if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
    Opcode = CSKY::LD32W;
  } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
    Opcode = CSKY::RESTORE_CARRY;
    CFI->setSpillsCR();
  } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
    Opcode = CSKY::FLD_S;
  else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
    Opcode = CSKY::FLD_D;
  else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
    Opcode = CSKY::f2FLD_S;
  else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
    Opcode = CSKY::f2FLD_D;
  else {
    llvm_unreachable("Unknown RegisterClass");
  }

  MachineMemOperand *MMO = MF.getMachineMemOperand(
      MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
      MFI.getObjectSize(FI), MFI.getObjectAlign(FI));

  BuildMI(MBB, I, DL, get(Opcode), DestReg)
      .addFrameIndex(FI)
      .addImm(0)
      .addMemOperand(MMO);
}

void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
                                MachineBasicBlock::iterator I,
                                const DebugLoc &DL, MCRegister DestReg,
                                MCRegister SrcReg, bool KillSrc,
                                bool RenamableDest, bool RenamableSrc) const {
  if (CSKY::GPRRegClass.contains(SrcReg) &&
      CSKY::CARRYRegClass.contains(DestReg)) {
    if (STI.hasE2()) {
      BuildMI(MBB, I, DL, get(CSKY::BTSTI32), DestReg)
          .addReg(SrcReg, getKillRegState(KillSrc))
          .addImm(0);
    } else {
      assert(SrcReg < CSKY::R8);
      BuildMI(MBB, I, DL, get(CSKY::BTSTI16), DestReg)
          .addReg(SrcReg, getKillRegState(KillSrc))
          .addImm(0);
    }
    return;
  }

  if (CSKY::CARRYRegClass.contains(SrcReg) &&
      CSKY::GPRRegClass.contains(DestReg)) {

    if (STI.hasE2()) {
      BuildMI(MBB, I, DL, get(CSKY::MVC32), DestReg)
          .addReg(SrcReg, getKillRegState(KillSrc));
    } else {
      assert(DestReg < CSKY::R16);
      assert(DestReg < CSKY::R8);
      BuildMI(MBB, I, DL, get(CSKY::MOVI16), DestReg).addImm(0);
      BuildMI(MBB, I, DL, get(CSKY::ADDC16))
          .addReg(DestReg, RegState::Define)
          .addReg(SrcReg, RegState::Define)
          .addReg(DestReg, getKillRegState(true))
          .addReg(DestReg, getKillRegState(true))
          .addReg(SrcReg, getKillRegState(true));
      BuildMI(MBB, I, DL, get(CSKY::BTSTI16))
          .addReg(SrcReg, RegState::Define | getDeadRegState(KillSrc))
          .addReg(DestReg)
          .addImm(0);
    }
    return;
  }

  unsigned Opcode = 0;
  if (CSKY::GPRRegClass.contains(DestReg, SrcReg))
    Opcode = STI.hasE2() ? CSKY::MOV32 : CSKY::MOV16;
  else if (v2sf && CSKY::sFPR32RegClass.contains(DestReg, SrcReg))
    Opcode = CSKY::FMOV_S;
  else if (v3sf && CSKY::FPR32RegClass.contains(DestReg, SrcReg))
    Opcode = CSKY::f2FMOV_S;
  else if (v2df && CSKY::sFPR64RegClass.contains(DestReg, SrcReg))
    Opcode = CSKY::FMOV_D;
  else if (v3df && CSKY::FPR64RegClass.contains(DestReg, SrcReg))
    Opcode = CSKY::f2FMOV_D;
  else if (v2sf && CSKY::sFPR32RegClass.contains(SrcReg) &&
           CSKY::GPRRegClass.contains(DestReg))
    Opcode = CSKY::FMFVRL;
  else if (v3sf && CSKY::FPR32RegClass.contains(SrcReg) &&
           CSKY::GPRRegClass.contains(DestReg))
    Opcode = CSKY::f2FMFVRL;
  else if (v2df && CSKY::sFPR64RegClass.contains(SrcReg) &&
           CSKY::GPRRegClass.contains(DestReg))
    Opcode = CSKY::FMFVRL_D;
  else if (v3df && CSKY::FPR64RegClass.contains(SrcReg) &&
           CSKY::GPRRegClass.contains(DestReg))
    Opcode = CSKY::f2FMFVRL_D;
  else if (v2sf && CSKY::GPRRegClass.contains(SrcReg) &&
           CSKY::sFPR32RegClass.contains(DestReg))
    Opcode = CSKY::FMTVRL;
  else if (v3sf && CSKY::GPRRegClass.contains(SrcReg) &&
           CSKY::FPR32RegClass.contains(DestReg))
    Opcode = CSKY::f2FMTVRL;
  else if (v2df && CSKY::GPRRegClass.contains(SrcReg) &&
           CSKY::sFPR64RegClass.contains(DestReg))
    Opcode = CSKY::FMTVRL_D;
  else if (v3df && CSKY::GPRRegClass.contains(SrcReg) &&
           CSKY::FPR64RegClass.contains(DestReg))
    Opcode = CSKY::f2FMTVRL_D;
  else {
    LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg);
    LLVM_DEBUG(I->dump());
    llvm_unreachable("Unknown RegisterClass");
  }

  BuildMI(MBB, I, DL, get(Opcode), DestReg)
      .addReg(SrcReg, getKillRegState(KillSrc));
}

Register CSKYInstrInfo::getGlobalBaseReg(MachineFunction &MF) const {
  CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
  MachineConstantPool *MCP = MF.getConstantPool();
  MachineRegisterInfo &MRI = MF.getRegInfo();

  Register GlobalBaseReg = CFI->getGlobalBaseReg();
  if (GlobalBaseReg != 0)
    return GlobalBaseReg;

  // Insert a pseudo instruction to set the GlobalBaseReg into the first
  // MBB of the function
  MachineBasicBlock &FirstMBB = MF.front();
  MachineBasicBlock::iterator MBBI = FirstMBB.begin();
  DebugLoc DL;

  CSKYConstantPoolValue *CPV = CSKYConstantPoolSymbol::Create(
      Type::getInt32Ty(MF.getFunction().getContext()), "_GLOBAL_OFFSET_TABLE_",
      0, CSKYCP::ADDR);

  unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));

  MachineMemOperand *MO =
      MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
                              MachineMemOperand::MOLoad, 4, Align(4));
  BuildMI(FirstMBB, MBBI, DL, get(CSKY::LRW32), CSKY::R28)
      .addConstantPoolIndex(CPI)
      .addMemOperand(MO);

  GlobalBaseReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);
  BuildMI(FirstMBB, MBBI, DL, get(TargetOpcode::COPY), GlobalBaseReg)
      .addReg(CSKY::R28);

  CFI->setGlobalBaseReg(GlobalBaseReg);
  return GlobalBaseReg;
}

unsigned CSKYInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
  switch (MI.getOpcode()) {
  default:
    return MI.getDesc().getSize();
  case CSKY::CONSTPOOL_ENTRY:
    return MI.getOperand(2).getImm();
  case CSKY::SPILL_CARRY:
  case CSKY::RESTORE_CARRY:
  case CSKY::PseudoTLSLA32:
    return 8;
  case TargetOpcode::INLINEASM_BR:
  case TargetOpcode::INLINEASM: {
    const MachineFunction *MF = MI.getParent()->getParent();
    const char *AsmStr = MI.getOperand(0).getSymbolName();
    return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
  }
  }
}
