//===-- 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;
}

unsigned 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;
}

unsigned 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) 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) 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) 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());
  }
  }
}
