xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1349cc55cSDimitry Andric //===-- CSKYInstrInfo.h - CSKY Instruction Information --------*- C++ -*---===//
2349cc55cSDimitry Andric //
3349cc55cSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4349cc55cSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5349cc55cSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6349cc55cSDimitry Andric //
7349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
8349cc55cSDimitry Andric //
9349cc55cSDimitry Andric // This file contains the CSKY implementation of the TargetInstrInfo class.
10349cc55cSDimitry Andric //
11349cc55cSDimitry Andric //===----------------------------------------------------------------------===//
12349cc55cSDimitry Andric 
13349cc55cSDimitry Andric #include "CSKYInstrInfo.h"
1404eeddc0SDimitry Andric #include "CSKYConstantPoolValue.h"
150eae32dcSDimitry Andric #include "CSKYMachineFunctionInfo.h"
160eae32dcSDimitry Andric #include "CSKYTargetMachine.h"
1781ad6265SDimitry Andric #include "llvm/CodeGen/MachineFrameInfo.h"
18349cc55cSDimitry Andric #include "llvm/MC/MCContext.h"
19349cc55cSDimitry Andric 
20349cc55cSDimitry Andric #define DEBUG_TYPE "csky-instr-info"
21349cc55cSDimitry Andric 
22349cc55cSDimitry Andric using namespace llvm;
23349cc55cSDimitry Andric 
24349cc55cSDimitry Andric #define GET_INSTRINFO_CTOR_DTOR
25349cc55cSDimitry Andric #include "CSKYGenInstrInfo.inc"
26349cc55cSDimitry Andric 
CSKYInstrInfo(CSKYSubtarget & STI)27349cc55cSDimitry Andric CSKYInstrInfo::CSKYInstrInfo(CSKYSubtarget &STI)
28349cc55cSDimitry Andric     : CSKYGenInstrInfo(CSKY::ADJCALLSTACKDOWN, CSKY::ADJCALLSTACKUP), STI(STI) {
2904eeddc0SDimitry Andric   v2sf = STI.hasFPUv2SingleFloat();
3004eeddc0SDimitry Andric   v2df = STI.hasFPUv2DoubleFloat();
3104eeddc0SDimitry Andric   v3sf = STI.hasFPUv3SingleFloat();
3204eeddc0SDimitry Andric   v3df = STI.hasFPUv3DoubleFloat();
3304eeddc0SDimitry Andric }
3404eeddc0SDimitry Andric 
parseCondBranch(MachineInstr & LastInst,MachineBasicBlock * & Target,SmallVectorImpl<MachineOperand> & Cond)3504eeddc0SDimitry Andric static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target,
3604eeddc0SDimitry Andric                             SmallVectorImpl<MachineOperand> &Cond) {
3704eeddc0SDimitry Andric   // Block ends with fall-through condbranch.
3804eeddc0SDimitry Andric   assert(LastInst.getDesc().isConditionalBranch() &&
3904eeddc0SDimitry Andric          "Unknown conditional branch");
4004eeddc0SDimitry Andric   Target = LastInst.getOperand(1).getMBB();
4104eeddc0SDimitry Andric   Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
4204eeddc0SDimitry Andric   Cond.push_back(LastInst.getOperand(0));
4304eeddc0SDimitry Andric }
4404eeddc0SDimitry Andric 
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const4504eeddc0SDimitry Andric bool CSKYInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
4604eeddc0SDimitry Andric                                   MachineBasicBlock *&TBB,
4704eeddc0SDimitry Andric                                   MachineBasicBlock *&FBB,
4804eeddc0SDimitry Andric                                   SmallVectorImpl<MachineOperand> &Cond,
4904eeddc0SDimitry Andric                                   bool AllowModify) const {
5004eeddc0SDimitry Andric   TBB = FBB = nullptr;
5104eeddc0SDimitry Andric   Cond.clear();
5204eeddc0SDimitry Andric 
5304eeddc0SDimitry Andric   // If the block has no terminators, it just falls into the block after it.
5404eeddc0SDimitry Andric   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
5504eeddc0SDimitry Andric   if (I == MBB.end() || !isUnpredicatedTerminator(*I))
5604eeddc0SDimitry Andric     return false;
5704eeddc0SDimitry Andric 
5804eeddc0SDimitry Andric   // Count the number of terminators and find the first unconditional or
5904eeddc0SDimitry Andric   // indirect branch.
6004eeddc0SDimitry Andric   MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
6104eeddc0SDimitry Andric   int NumTerminators = 0;
6204eeddc0SDimitry Andric   for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
6304eeddc0SDimitry Andric        J++) {
6404eeddc0SDimitry Andric     NumTerminators++;
6504eeddc0SDimitry Andric     if (J->getDesc().isUnconditionalBranch() ||
6604eeddc0SDimitry Andric         J->getDesc().isIndirectBranch()) {
6704eeddc0SDimitry Andric       FirstUncondOrIndirectBr = J.getReverse();
6804eeddc0SDimitry Andric     }
6904eeddc0SDimitry Andric   }
7004eeddc0SDimitry Andric 
7104eeddc0SDimitry Andric   // If AllowModify is true, we can erase any terminators after
7204eeddc0SDimitry Andric   // FirstUncondOrIndirectBR.
7304eeddc0SDimitry Andric   if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
7404eeddc0SDimitry Andric     while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
7504eeddc0SDimitry Andric       std::next(FirstUncondOrIndirectBr)->eraseFromParent();
7604eeddc0SDimitry Andric       NumTerminators--;
7704eeddc0SDimitry Andric     }
7804eeddc0SDimitry Andric     I = FirstUncondOrIndirectBr;
7904eeddc0SDimitry Andric   }
8004eeddc0SDimitry Andric 
8104eeddc0SDimitry Andric   // We can't handle blocks that end in an indirect branch.
8204eeddc0SDimitry Andric   if (I->getDesc().isIndirectBranch())
8304eeddc0SDimitry Andric     return true;
8404eeddc0SDimitry Andric 
8504eeddc0SDimitry Andric   // We can't handle blocks with more than 2 terminators.
8604eeddc0SDimitry Andric   if (NumTerminators > 2)
8704eeddc0SDimitry Andric     return true;
8804eeddc0SDimitry Andric 
8904eeddc0SDimitry Andric   // Handle a single unconditional branch.
9004eeddc0SDimitry Andric   if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
9104eeddc0SDimitry Andric     TBB = getBranchDestBlock(*I);
9204eeddc0SDimitry Andric     return false;
9304eeddc0SDimitry Andric   }
9404eeddc0SDimitry Andric 
9504eeddc0SDimitry Andric   // Handle a single conditional branch.
9604eeddc0SDimitry Andric   if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
9704eeddc0SDimitry Andric     parseCondBranch(*I, TBB, Cond);
9804eeddc0SDimitry Andric     return false;
9904eeddc0SDimitry Andric   }
10004eeddc0SDimitry Andric 
10104eeddc0SDimitry Andric   // Handle a conditional branch followed by an unconditional branch.
10204eeddc0SDimitry Andric   if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
10304eeddc0SDimitry Andric       I->getDesc().isUnconditionalBranch()) {
10404eeddc0SDimitry Andric     parseCondBranch(*std::prev(I), TBB, Cond);
10504eeddc0SDimitry Andric     FBB = getBranchDestBlock(*I);
10604eeddc0SDimitry Andric     return false;
10704eeddc0SDimitry Andric   }
10804eeddc0SDimitry Andric 
10904eeddc0SDimitry Andric   // Otherwise, we can't handle this.
11004eeddc0SDimitry Andric   return true;
11104eeddc0SDimitry Andric }
11204eeddc0SDimitry Andric 
removeBranch(MachineBasicBlock & MBB,int * BytesRemoved) const11304eeddc0SDimitry Andric unsigned CSKYInstrInfo::removeBranch(MachineBasicBlock &MBB,
11404eeddc0SDimitry Andric                                      int *BytesRemoved) const {
11504eeddc0SDimitry Andric   if (BytesRemoved)
11604eeddc0SDimitry Andric     *BytesRemoved = 0;
11704eeddc0SDimitry Andric   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
11804eeddc0SDimitry Andric   if (I == MBB.end())
11904eeddc0SDimitry Andric     return 0;
12004eeddc0SDimitry Andric 
12104eeddc0SDimitry Andric   if (!I->getDesc().isUnconditionalBranch() &&
12204eeddc0SDimitry Andric       !I->getDesc().isConditionalBranch())
12304eeddc0SDimitry Andric     return 0;
12404eeddc0SDimitry Andric 
12504eeddc0SDimitry Andric   // Remove the branch.
12604eeddc0SDimitry Andric   if (BytesRemoved)
12704eeddc0SDimitry Andric     *BytesRemoved += getInstSizeInBytes(*I);
12804eeddc0SDimitry Andric   I->eraseFromParent();
12904eeddc0SDimitry Andric 
13004eeddc0SDimitry Andric   I = MBB.end();
13104eeddc0SDimitry Andric 
13204eeddc0SDimitry Andric   if (I == MBB.begin())
13304eeddc0SDimitry Andric     return 1;
13404eeddc0SDimitry Andric   --I;
13504eeddc0SDimitry Andric   if (!I->getDesc().isConditionalBranch())
13604eeddc0SDimitry Andric     return 1;
13704eeddc0SDimitry Andric 
13804eeddc0SDimitry Andric   // Remove the branch.
13904eeddc0SDimitry Andric   if (BytesRemoved)
14004eeddc0SDimitry Andric     *BytesRemoved += getInstSizeInBytes(*I);
14104eeddc0SDimitry Andric   I->eraseFromParent();
14204eeddc0SDimitry Andric   return 2;
14304eeddc0SDimitry Andric }
14404eeddc0SDimitry Andric 
14504eeddc0SDimitry Andric MachineBasicBlock *
getBranchDestBlock(const MachineInstr & MI) const14604eeddc0SDimitry Andric CSKYInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
14704eeddc0SDimitry Andric   assert(MI.getDesc().isBranch() && "Unexpected opcode!");
14804eeddc0SDimitry Andric   // The branch target is always the last operand.
14904eeddc0SDimitry Andric   int NumOp = MI.getNumExplicitOperands();
15004eeddc0SDimitry Andric   assert(MI.getOperand(NumOp - 1).isMBB() && "Expected MBB!");
15104eeddc0SDimitry Andric   return MI.getOperand(NumOp - 1).getMBB();
15204eeddc0SDimitry Andric }
15304eeddc0SDimitry Andric 
insertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL,int * BytesAdded) const15404eeddc0SDimitry Andric unsigned CSKYInstrInfo::insertBranch(
15504eeddc0SDimitry Andric     MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
15604eeddc0SDimitry Andric     ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
15704eeddc0SDimitry Andric   if (BytesAdded)
15804eeddc0SDimitry Andric     *BytesAdded = 0;
15904eeddc0SDimitry Andric 
16004eeddc0SDimitry Andric   // Shouldn't be a fall through.
16104eeddc0SDimitry Andric   assert(TBB && "insertBranch must not be told to insert a fallthrough");
16204eeddc0SDimitry Andric   assert((Cond.size() == 2 || Cond.size() == 0) &&
16304eeddc0SDimitry Andric          "CSKY branch conditions have two components!");
16404eeddc0SDimitry Andric 
16504eeddc0SDimitry Andric   // Unconditional branch.
16604eeddc0SDimitry Andric   if (Cond.empty()) {
16704eeddc0SDimitry Andric     MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(TBB);
16804eeddc0SDimitry Andric     if (BytesAdded)
16904eeddc0SDimitry Andric       *BytesAdded += getInstSizeInBytes(MI);
17004eeddc0SDimitry Andric     return 1;
17104eeddc0SDimitry Andric   }
17204eeddc0SDimitry Andric 
17304eeddc0SDimitry Andric   // Either a one or two-way conditional branch.
17404eeddc0SDimitry Andric   unsigned Opc = Cond[0].getImm();
17504eeddc0SDimitry Andric   MachineInstr &CondMI = *BuildMI(&MBB, DL, get(Opc)).add(Cond[1]).addMBB(TBB);
17604eeddc0SDimitry Andric   if (BytesAdded)
17704eeddc0SDimitry Andric     *BytesAdded += getInstSizeInBytes(CondMI);
17804eeddc0SDimitry Andric 
17904eeddc0SDimitry Andric   // One-way conditional branch.
18004eeddc0SDimitry Andric   if (!FBB)
18104eeddc0SDimitry Andric     return 1;
18204eeddc0SDimitry Andric 
18304eeddc0SDimitry Andric   // Two-way conditional branch.
18404eeddc0SDimitry Andric   MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(FBB);
18504eeddc0SDimitry Andric   if (BytesAdded)
18604eeddc0SDimitry Andric     *BytesAdded += getInstSizeInBytes(MI);
18704eeddc0SDimitry Andric   return 2;
18804eeddc0SDimitry Andric }
18904eeddc0SDimitry Andric 
getOppositeBranchOpc(unsigned Opcode)19004eeddc0SDimitry Andric static unsigned getOppositeBranchOpc(unsigned Opcode) {
19104eeddc0SDimitry Andric   switch (Opcode) {
19204eeddc0SDimitry Andric   default:
19304eeddc0SDimitry Andric     llvm_unreachable("Unknown conditional branch!");
19404eeddc0SDimitry Andric   case CSKY::BT32:
19504eeddc0SDimitry Andric     return CSKY::BF32;
19604eeddc0SDimitry Andric   case CSKY::BT16:
19704eeddc0SDimitry Andric     return CSKY::BF16;
19804eeddc0SDimitry Andric   case CSKY::BF32:
19904eeddc0SDimitry Andric     return CSKY::BT32;
20004eeddc0SDimitry Andric   case CSKY::BF16:
20104eeddc0SDimitry Andric     return CSKY::BT16;
20204eeddc0SDimitry Andric   case CSKY::BHZ32:
20304eeddc0SDimitry Andric     return CSKY::BLSZ32;
20404eeddc0SDimitry Andric   case CSKY::BHSZ32:
20504eeddc0SDimitry Andric     return CSKY::BLZ32;
20604eeddc0SDimitry Andric   case CSKY::BLZ32:
20704eeddc0SDimitry Andric     return CSKY::BHSZ32;
20804eeddc0SDimitry Andric   case CSKY::BLSZ32:
20904eeddc0SDimitry Andric     return CSKY::BHZ32;
21004eeddc0SDimitry Andric   case CSKY::BNEZ32:
21104eeddc0SDimitry Andric     return CSKY::BEZ32;
21204eeddc0SDimitry Andric   case CSKY::BEZ32:
21304eeddc0SDimitry Andric     return CSKY::BNEZ32;
21404eeddc0SDimitry Andric   }
21504eeddc0SDimitry Andric }
21604eeddc0SDimitry Andric 
reverseBranchCondition(SmallVectorImpl<MachineOperand> & Cond) const21704eeddc0SDimitry Andric bool CSKYInstrInfo::reverseBranchCondition(
21804eeddc0SDimitry Andric     SmallVectorImpl<MachineOperand> &Cond) const {
21904eeddc0SDimitry Andric   assert((Cond.size() == 2) && "Invalid branch condition!");
22004eeddc0SDimitry Andric   Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm()));
22104eeddc0SDimitry Andric   return false;
222349cc55cSDimitry Andric }
2230eae32dcSDimitry Andric 
movImm(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,const DebugLoc & DL,uint64_t Val,MachineInstr::MIFlag Flag) const2240eae32dcSDimitry Andric Register CSKYInstrInfo::movImm(MachineBasicBlock &MBB,
2250eae32dcSDimitry Andric                                MachineBasicBlock::iterator MBBI,
22681ad6265SDimitry Andric                                const DebugLoc &DL, uint64_t Val,
2270eae32dcSDimitry Andric                                MachineInstr::MIFlag Flag) const {
22881ad6265SDimitry Andric   if (!isInt<32>(Val))
22981ad6265SDimitry Andric     report_fatal_error("Should only materialize 32-bit constants.");
2300eae32dcSDimitry Andric 
2310eae32dcSDimitry Andric   MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
2320eae32dcSDimitry Andric 
2330eae32dcSDimitry Andric   Register DstReg;
2340eae32dcSDimitry Andric   if (STI.hasE2()) {
2350eae32dcSDimitry Andric     DstReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);
2360eae32dcSDimitry Andric 
2370eae32dcSDimitry Andric     if (isUInt<16>(Val)) {
2380eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI32), DstReg)
2390eae32dcSDimitry Andric           .addImm(Val & 0xFFFF)
2400eae32dcSDimitry Andric           .setMIFlags(Flag);
2410eae32dcSDimitry Andric     } else if (isShiftedUInt<16, 16>(Val)) {
2420eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg)
2430eae32dcSDimitry Andric           .addImm((Val >> 16) & 0xFFFF)
2440eae32dcSDimitry Andric           .setMIFlags(Flag);
2450eae32dcSDimitry Andric     } else {
2460eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg)
2470eae32dcSDimitry Andric           .addImm((Val >> 16) & 0xFFFF)
2480eae32dcSDimitry Andric           .setMIFlags(Flag);
2490eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::ORI32), DstReg)
2500eae32dcSDimitry Andric           .addReg(DstReg)
2510eae32dcSDimitry Andric           .addImm(Val & 0xFFFF)
2520eae32dcSDimitry Andric           .setMIFlags(Flag);
2530eae32dcSDimitry Andric     }
2540eae32dcSDimitry Andric 
2550eae32dcSDimitry Andric   } else {
2560eae32dcSDimitry Andric     DstReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass);
2570eae32dcSDimitry Andric     if (isUInt<8>(Val)) {
2580eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
2590eae32dcSDimitry Andric           .addImm(Val & 0xFF)
2600eae32dcSDimitry Andric           .setMIFlags(Flag);
2610eae32dcSDimitry Andric     } else if (isUInt<16>(Val)) {
2620eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
2630eae32dcSDimitry Andric           .addImm((Val >> 8) & 0xFF)
2640eae32dcSDimitry Andric           .setMIFlags(Flag);
2650eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
2660eae32dcSDimitry Andric           .addReg(DstReg)
2670eae32dcSDimitry Andric           .addImm(8)
2680eae32dcSDimitry Andric           .setMIFlags(Flag);
2690eae32dcSDimitry Andric       if ((Val & 0xFF) != 0)
2700eae32dcSDimitry Andric         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
2710eae32dcSDimitry Andric             .addReg(DstReg)
2720eae32dcSDimitry Andric             .addImm(Val & 0xFF)
2730eae32dcSDimitry Andric             .setMIFlags(Flag);
2740eae32dcSDimitry Andric     } else if (isUInt<24>(Val)) {
2750eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
2760eae32dcSDimitry Andric           .addImm((Val >> 16) & 0xFF)
2770eae32dcSDimitry Andric           .setMIFlags(Flag);
2780eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
2790eae32dcSDimitry Andric           .addReg(DstReg)
2800eae32dcSDimitry Andric           .addImm(8)
2810eae32dcSDimitry Andric           .setMIFlags(Flag);
2820eae32dcSDimitry Andric       if (((Val >> 8) & 0xFF) != 0)
2830eae32dcSDimitry Andric         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
2840eae32dcSDimitry Andric             .addReg(DstReg)
2850eae32dcSDimitry Andric             .addImm((Val >> 8) & 0xFF)
2860eae32dcSDimitry Andric             .setMIFlags(Flag);
2870eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
2880eae32dcSDimitry Andric           .addReg(DstReg)
2890eae32dcSDimitry Andric           .addImm(8)
2900eae32dcSDimitry Andric           .setMIFlags(Flag);
2910eae32dcSDimitry Andric       if ((Val & 0xFF) != 0)
2920eae32dcSDimitry Andric         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
2930eae32dcSDimitry Andric             .addReg(DstReg)
2940eae32dcSDimitry Andric             .addImm(Val & 0xFF)
2950eae32dcSDimitry Andric             .setMIFlags(Flag);
2960eae32dcSDimitry Andric     } else {
2970eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
2980eae32dcSDimitry Andric           .addImm((Val >> 24) & 0xFF)
2990eae32dcSDimitry Andric           .setMIFlags(Flag);
3000eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
3010eae32dcSDimitry Andric           .addReg(DstReg)
3020eae32dcSDimitry Andric           .addImm(8)
3030eae32dcSDimitry Andric           .setMIFlags(Flag);
3040eae32dcSDimitry Andric       if (((Val >> 16) & 0xFF) != 0)
3050eae32dcSDimitry Andric         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
3060eae32dcSDimitry Andric             .addReg(DstReg)
3070eae32dcSDimitry Andric             .addImm((Val >> 16) & 0xFF)
3080eae32dcSDimitry Andric             .setMIFlags(Flag);
3090eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
3100eae32dcSDimitry Andric           .addReg(DstReg)
3110eae32dcSDimitry Andric           .addImm(8)
3120eae32dcSDimitry Andric           .setMIFlags(Flag);
3130eae32dcSDimitry Andric       if (((Val >> 8) & 0xFF) != 0)
3140eae32dcSDimitry Andric         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
3150eae32dcSDimitry Andric             .addReg(DstReg)
3160eae32dcSDimitry Andric             .addImm((Val >> 8) & 0xFF)
3170eae32dcSDimitry Andric             .setMIFlags(Flag);
3180eae32dcSDimitry Andric       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
3190eae32dcSDimitry Andric           .addReg(DstReg)
3200eae32dcSDimitry Andric           .addImm(8)
3210eae32dcSDimitry Andric           .setMIFlags(Flag);
3220eae32dcSDimitry Andric       if ((Val & 0xFF) != 0)
3230eae32dcSDimitry Andric         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
3240eae32dcSDimitry Andric             .addReg(DstReg)
3250eae32dcSDimitry Andric             .addImm(Val & 0xFF)
3260eae32dcSDimitry Andric             .setMIFlags(Flag);
3270eae32dcSDimitry Andric     }
3280eae32dcSDimitry Andric   }
3290eae32dcSDimitry Andric 
3300eae32dcSDimitry Andric   return DstReg;
3310eae32dcSDimitry Andric }
3320eae32dcSDimitry Andric 
isLoadFromStackSlot(const MachineInstr & MI,int & FrameIndex) const333*0fca6ea1SDimitry Andric Register CSKYInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
3340eae32dcSDimitry Andric                                             int &FrameIndex) const {
3350eae32dcSDimitry Andric   switch (MI.getOpcode()) {
3360eae32dcSDimitry Andric   default:
3370eae32dcSDimitry Andric     return 0;
3380eae32dcSDimitry Andric   case CSKY::LD16B:
3390eae32dcSDimitry Andric   case CSKY::LD16H:
3400eae32dcSDimitry Andric   case CSKY::LD16W:
3410eae32dcSDimitry Andric   case CSKY::LD32B:
3420eae32dcSDimitry Andric   case CSKY::LD32BS:
3430eae32dcSDimitry Andric   case CSKY::LD32H:
3440eae32dcSDimitry Andric   case CSKY::LD32HS:
3450eae32dcSDimitry Andric   case CSKY::LD32W:
34604eeddc0SDimitry Andric   case CSKY::FLD_S:
34704eeddc0SDimitry Andric   case CSKY::FLD_D:
34804eeddc0SDimitry Andric   case CSKY::f2FLD_S:
34904eeddc0SDimitry Andric   case CSKY::f2FLD_D:
3500eae32dcSDimitry Andric   case CSKY::RESTORE_CARRY:
3510eae32dcSDimitry Andric     break;
3520eae32dcSDimitry Andric   }
3530eae32dcSDimitry Andric 
3540eae32dcSDimitry Andric   if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
3550eae32dcSDimitry Andric       MI.getOperand(2).getImm() == 0) {
3560eae32dcSDimitry Andric     FrameIndex = MI.getOperand(1).getIndex();
3570eae32dcSDimitry Andric     return MI.getOperand(0).getReg();
3580eae32dcSDimitry Andric   }
3590eae32dcSDimitry Andric 
3600eae32dcSDimitry Andric   return 0;
3610eae32dcSDimitry Andric }
3620eae32dcSDimitry Andric 
isStoreToStackSlot(const MachineInstr & MI,int & FrameIndex) const363*0fca6ea1SDimitry Andric Register CSKYInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
3640eae32dcSDimitry Andric                                            int &FrameIndex) const {
3650eae32dcSDimitry Andric   switch (MI.getOpcode()) {
3660eae32dcSDimitry Andric   default:
3670eae32dcSDimitry Andric     return 0;
3680eae32dcSDimitry Andric   case CSKY::ST16B:
3690eae32dcSDimitry Andric   case CSKY::ST16H:
3700eae32dcSDimitry Andric   case CSKY::ST16W:
3710eae32dcSDimitry Andric   case CSKY::ST32B:
3720eae32dcSDimitry Andric   case CSKY::ST32H:
3730eae32dcSDimitry Andric   case CSKY::ST32W:
37404eeddc0SDimitry Andric   case CSKY::FST_S:
37504eeddc0SDimitry Andric   case CSKY::FST_D:
37604eeddc0SDimitry Andric   case CSKY::f2FST_S:
37704eeddc0SDimitry Andric   case CSKY::f2FST_D:
3780eae32dcSDimitry Andric   case CSKY::SPILL_CARRY:
3790eae32dcSDimitry Andric     break;
3800eae32dcSDimitry Andric   }
3810eae32dcSDimitry Andric 
3820eae32dcSDimitry Andric   if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
3830eae32dcSDimitry Andric       MI.getOperand(2).getImm() == 0) {
3840eae32dcSDimitry Andric     FrameIndex = MI.getOperand(1).getIndex();
3850eae32dcSDimitry Andric     return MI.getOperand(0).getReg();
3860eae32dcSDimitry Andric   }
3870eae32dcSDimitry Andric 
3880eae32dcSDimitry Andric   return 0;
3890eae32dcSDimitry Andric }
3900eae32dcSDimitry Andric 
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,Register SrcReg,bool IsKill,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,Register VReg) const3910eae32dcSDimitry Andric void CSKYInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
3920eae32dcSDimitry Andric                                         MachineBasicBlock::iterator I,
3930eae32dcSDimitry Andric                                         Register SrcReg, bool IsKill, int FI,
3940eae32dcSDimitry Andric                                         const TargetRegisterClass *RC,
395bdd1243dSDimitry Andric                                         const TargetRegisterInfo *TRI,
396bdd1243dSDimitry Andric                                         Register VReg) const {
3970eae32dcSDimitry Andric   DebugLoc DL;
3980eae32dcSDimitry Andric   if (I != MBB.end())
3990eae32dcSDimitry Andric     DL = I->getDebugLoc();
4000eae32dcSDimitry Andric 
4010eae32dcSDimitry Andric   MachineFunction &MF = *MBB.getParent();
4020eae32dcSDimitry Andric   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
4030eae32dcSDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
4040eae32dcSDimitry Andric 
4050eae32dcSDimitry Andric   unsigned Opcode = 0;
4060eae32dcSDimitry Andric 
4070eae32dcSDimitry Andric   if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
4080eae32dcSDimitry Andric     Opcode = CSKY::ST32W; // Optimize for 16bit
4090eae32dcSDimitry Andric   } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
4100eae32dcSDimitry Andric     Opcode = CSKY::SPILL_CARRY;
4110eae32dcSDimitry Andric     CFI->setSpillsCR();
41204eeddc0SDimitry Andric   } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
41304eeddc0SDimitry Andric     Opcode = CSKY::FST_S;
41404eeddc0SDimitry Andric   else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
41504eeddc0SDimitry Andric     Opcode = CSKY::FST_D;
41604eeddc0SDimitry Andric   else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
41704eeddc0SDimitry Andric     Opcode = CSKY::f2FST_S;
41804eeddc0SDimitry Andric   else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
41904eeddc0SDimitry Andric     Opcode = CSKY::f2FST_D;
42004eeddc0SDimitry Andric   else {
4210eae32dcSDimitry Andric     llvm_unreachable("Unknown RegisterClass");
4220eae32dcSDimitry Andric   }
4230eae32dcSDimitry Andric 
4240eae32dcSDimitry Andric   MachineMemOperand *MMO = MF.getMachineMemOperand(
4250eae32dcSDimitry Andric       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
4260eae32dcSDimitry Andric       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
4270eae32dcSDimitry Andric 
4280eae32dcSDimitry Andric   BuildMI(MBB, I, DL, get(Opcode))
4290eae32dcSDimitry Andric       .addReg(SrcReg, getKillRegState(IsKill))
4300eae32dcSDimitry Andric       .addFrameIndex(FI)
4310eae32dcSDimitry Andric       .addImm(0)
4320eae32dcSDimitry Andric       .addMemOperand(MMO);
4330eae32dcSDimitry Andric }
4340eae32dcSDimitry Andric 
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,Register DestReg,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,Register VReg) const4350eae32dcSDimitry Andric void CSKYInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
4360eae32dcSDimitry Andric                                          MachineBasicBlock::iterator I,
4370eae32dcSDimitry Andric                                          Register DestReg, int FI,
4380eae32dcSDimitry Andric                                          const TargetRegisterClass *RC,
439bdd1243dSDimitry Andric                                          const TargetRegisterInfo *TRI,
440bdd1243dSDimitry Andric                                          Register VReg) const {
4410eae32dcSDimitry Andric   DebugLoc DL;
4420eae32dcSDimitry Andric   if (I != MBB.end())
4430eae32dcSDimitry Andric     DL = I->getDebugLoc();
4440eae32dcSDimitry Andric 
4450eae32dcSDimitry Andric   MachineFunction &MF = *MBB.getParent();
4460eae32dcSDimitry Andric   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
4470eae32dcSDimitry Andric   MachineFrameInfo &MFI = MF.getFrameInfo();
4480eae32dcSDimitry Andric 
4490eae32dcSDimitry Andric   unsigned Opcode = 0;
4500eae32dcSDimitry Andric 
4510eae32dcSDimitry Andric   if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
4520eae32dcSDimitry Andric     Opcode = CSKY::LD32W;
4530eae32dcSDimitry Andric   } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
4540eae32dcSDimitry Andric     Opcode = CSKY::RESTORE_CARRY;
4550eae32dcSDimitry Andric     CFI->setSpillsCR();
45604eeddc0SDimitry Andric   } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
45704eeddc0SDimitry Andric     Opcode = CSKY::FLD_S;
45804eeddc0SDimitry Andric   else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
45904eeddc0SDimitry Andric     Opcode = CSKY::FLD_D;
46004eeddc0SDimitry Andric   else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
46104eeddc0SDimitry Andric     Opcode = CSKY::f2FLD_S;
46204eeddc0SDimitry Andric   else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
46304eeddc0SDimitry Andric     Opcode = CSKY::f2FLD_D;
46404eeddc0SDimitry Andric   else {
4650eae32dcSDimitry Andric     llvm_unreachable("Unknown RegisterClass");
4660eae32dcSDimitry Andric   }
4670eae32dcSDimitry Andric 
4680eae32dcSDimitry Andric   MachineMemOperand *MMO = MF.getMachineMemOperand(
4690eae32dcSDimitry Andric       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
4700eae32dcSDimitry Andric       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
4710eae32dcSDimitry Andric 
4720eae32dcSDimitry Andric   BuildMI(MBB, I, DL, get(Opcode), DestReg)
4730eae32dcSDimitry Andric       .addFrameIndex(FI)
4740eae32dcSDimitry Andric       .addImm(0)
4750eae32dcSDimitry Andric       .addMemOperand(MMO);
4760eae32dcSDimitry Andric }
4770eae32dcSDimitry Andric 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,const DebugLoc & DL,MCRegister DestReg,MCRegister SrcReg,bool KillSrc) const4780eae32dcSDimitry Andric void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
4790eae32dcSDimitry Andric                                 MachineBasicBlock::iterator I,
4800eae32dcSDimitry Andric                                 const DebugLoc &DL, MCRegister DestReg,
4810eae32dcSDimitry Andric                                 MCRegister SrcReg, bool KillSrc) const {
4820eae32dcSDimitry Andric   if (CSKY::GPRRegClass.contains(SrcReg) &&
4830eae32dcSDimitry Andric       CSKY::CARRYRegClass.contains(DestReg)) {
4840eae32dcSDimitry Andric     if (STI.hasE2()) {
4850eae32dcSDimitry Andric       BuildMI(MBB, I, DL, get(CSKY::BTSTI32), DestReg)
4860eae32dcSDimitry Andric           .addReg(SrcReg, getKillRegState(KillSrc))
4870eae32dcSDimitry Andric           .addImm(0);
4880eae32dcSDimitry Andric     } else {
4890eae32dcSDimitry Andric       assert(SrcReg < CSKY::R8);
4900eae32dcSDimitry Andric       BuildMI(MBB, I, DL, get(CSKY::BTSTI16), DestReg)
4910eae32dcSDimitry Andric           .addReg(SrcReg, getKillRegState(KillSrc))
4920eae32dcSDimitry Andric           .addImm(0);
4930eae32dcSDimitry Andric     }
4940eae32dcSDimitry Andric     return;
4950eae32dcSDimitry Andric   }
4960eae32dcSDimitry Andric 
4970eae32dcSDimitry Andric   if (CSKY::CARRYRegClass.contains(SrcReg) &&
4980eae32dcSDimitry Andric       CSKY::GPRRegClass.contains(DestReg)) {
4990eae32dcSDimitry Andric 
5000eae32dcSDimitry Andric     if (STI.hasE2()) {
5010eae32dcSDimitry Andric       BuildMI(MBB, I, DL, get(CSKY::MVC32), DestReg)
5020eae32dcSDimitry Andric           .addReg(SrcReg, getKillRegState(KillSrc));
5030eae32dcSDimitry Andric     } else {
5040eae32dcSDimitry Andric       assert(DestReg < CSKY::R16);
5050eae32dcSDimitry Andric       assert(DestReg < CSKY::R8);
5060eae32dcSDimitry Andric       BuildMI(MBB, I, DL, get(CSKY::MOVI16), DestReg).addImm(0);
5070eae32dcSDimitry Andric       BuildMI(MBB, I, DL, get(CSKY::ADDC16))
5080eae32dcSDimitry Andric           .addReg(DestReg, RegState::Define)
5090eae32dcSDimitry Andric           .addReg(SrcReg, RegState::Define)
5100eae32dcSDimitry Andric           .addReg(DestReg, getKillRegState(true))
5110eae32dcSDimitry Andric           .addReg(DestReg, getKillRegState(true))
5120eae32dcSDimitry Andric           .addReg(SrcReg, getKillRegState(true));
5130eae32dcSDimitry Andric       BuildMI(MBB, I, DL, get(CSKY::BTSTI16))
5140eae32dcSDimitry Andric           .addReg(SrcReg, RegState::Define | getDeadRegState(KillSrc))
5150eae32dcSDimitry Andric           .addReg(DestReg)
5160eae32dcSDimitry Andric           .addImm(0);
5170eae32dcSDimitry Andric     }
5180eae32dcSDimitry Andric     return;
5190eae32dcSDimitry Andric   }
5200eae32dcSDimitry Andric 
5210eae32dcSDimitry Andric   unsigned Opcode = 0;
5220eae32dcSDimitry Andric   if (CSKY::GPRRegClass.contains(DestReg, SrcReg))
523fcaf7f86SDimitry Andric     Opcode = STI.hasE2() ? CSKY::MOV32 : CSKY::MOV16;
52404eeddc0SDimitry Andric   else if (v2sf && CSKY::sFPR32RegClass.contains(DestReg, SrcReg))
52504eeddc0SDimitry Andric     Opcode = CSKY::FMOV_S;
52604eeddc0SDimitry Andric   else if (v3sf && CSKY::FPR32RegClass.contains(DestReg, SrcReg))
52704eeddc0SDimitry Andric     Opcode = CSKY::f2FMOV_S;
52804eeddc0SDimitry Andric   else if (v2df && CSKY::sFPR64RegClass.contains(DestReg, SrcReg))
52904eeddc0SDimitry Andric     Opcode = CSKY::FMOV_D;
53004eeddc0SDimitry Andric   else if (v3df && CSKY::FPR64RegClass.contains(DestReg, SrcReg))
53104eeddc0SDimitry Andric     Opcode = CSKY::f2FMOV_D;
53204eeddc0SDimitry Andric   else if (v2sf && CSKY::sFPR32RegClass.contains(SrcReg) &&
53304eeddc0SDimitry Andric            CSKY::GPRRegClass.contains(DestReg))
53404eeddc0SDimitry Andric     Opcode = CSKY::FMFVRL;
53504eeddc0SDimitry Andric   else if (v3sf && CSKY::FPR32RegClass.contains(SrcReg) &&
53604eeddc0SDimitry Andric            CSKY::GPRRegClass.contains(DestReg))
53704eeddc0SDimitry Andric     Opcode = CSKY::f2FMFVRL;
53804eeddc0SDimitry Andric   else if (v2df && CSKY::sFPR64RegClass.contains(SrcReg) &&
53904eeddc0SDimitry Andric            CSKY::GPRRegClass.contains(DestReg))
54004eeddc0SDimitry Andric     Opcode = CSKY::FMFVRL_D;
54104eeddc0SDimitry Andric   else if (v3df && CSKY::FPR64RegClass.contains(SrcReg) &&
54204eeddc0SDimitry Andric            CSKY::GPRRegClass.contains(DestReg))
54304eeddc0SDimitry Andric     Opcode = CSKY::f2FMFVRL_D;
54404eeddc0SDimitry Andric   else if (v2sf && CSKY::GPRRegClass.contains(SrcReg) &&
54504eeddc0SDimitry Andric            CSKY::sFPR32RegClass.contains(DestReg))
54604eeddc0SDimitry Andric     Opcode = CSKY::FMTVRL;
54704eeddc0SDimitry Andric   else if (v3sf && CSKY::GPRRegClass.contains(SrcReg) &&
54804eeddc0SDimitry Andric            CSKY::FPR32RegClass.contains(DestReg))
54904eeddc0SDimitry Andric     Opcode = CSKY::f2FMTVRL;
55004eeddc0SDimitry Andric   else if (v2df && CSKY::GPRRegClass.contains(SrcReg) &&
55104eeddc0SDimitry Andric            CSKY::sFPR64RegClass.contains(DestReg))
55204eeddc0SDimitry Andric     Opcode = CSKY::FMTVRL_D;
55304eeddc0SDimitry Andric   else if (v3df && CSKY::GPRRegClass.contains(SrcReg) &&
55404eeddc0SDimitry Andric            CSKY::FPR64RegClass.contains(DestReg))
55504eeddc0SDimitry Andric     Opcode = CSKY::f2FMTVRL_D;
5560eae32dcSDimitry Andric   else {
5570eae32dcSDimitry Andric     LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg);
5580eae32dcSDimitry Andric     LLVM_DEBUG(I->dump());
5590eae32dcSDimitry Andric     llvm_unreachable("Unknown RegisterClass");
5600eae32dcSDimitry Andric   }
5610eae32dcSDimitry Andric 
5620eae32dcSDimitry Andric   BuildMI(MBB, I, DL, get(Opcode), DestReg)
5630eae32dcSDimitry Andric       .addReg(SrcReg, getKillRegState(KillSrc));
5640eae32dcSDimitry Andric }
56504eeddc0SDimitry Andric 
getGlobalBaseReg(MachineFunction & MF) const56604eeddc0SDimitry Andric Register CSKYInstrInfo::getGlobalBaseReg(MachineFunction &MF) const {
56704eeddc0SDimitry Andric   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
56804eeddc0SDimitry Andric   MachineConstantPool *MCP = MF.getConstantPool();
56904eeddc0SDimitry Andric   MachineRegisterInfo &MRI = MF.getRegInfo();
57004eeddc0SDimitry Andric 
57104eeddc0SDimitry Andric   Register GlobalBaseReg = CFI->getGlobalBaseReg();
57204eeddc0SDimitry Andric   if (GlobalBaseReg != 0)
57304eeddc0SDimitry Andric     return GlobalBaseReg;
57404eeddc0SDimitry Andric 
57504eeddc0SDimitry Andric   // Insert a pseudo instruction to set the GlobalBaseReg into the first
57604eeddc0SDimitry Andric   // MBB of the function
57704eeddc0SDimitry Andric   MachineBasicBlock &FirstMBB = MF.front();
57804eeddc0SDimitry Andric   MachineBasicBlock::iterator MBBI = FirstMBB.begin();
57904eeddc0SDimitry Andric   DebugLoc DL;
58004eeddc0SDimitry Andric 
58104eeddc0SDimitry Andric   CSKYConstantPoolValue *CPV = CSKYConstantPoolSymbol::Create(
58204eeddc0SDimitry Andric       Type::getInt32Ty(MF.getFunction().getContext()), "_GLOBAL_OFFSET_TABLE_",
58304eeddc0SDimitry Andric       0, CSKYCP::ADDR);
58404eeddc0SDimitry Andric 
58504eeddc0SDimitry Andric   unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));
58604eeddc0SDimitry Andric 
58704eeddc0SDimitry Andric   MachineMemOperand *MO =
58804eeddc0SDimitry Andric       MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
58904eeddc0SDimitry Andric                               MachineMemOperand::MOLoad, 4, Align(4));
59004eeddc0SDimitry Andric   BuildMI(FirstMBB, MBBI, DL, get(CSKY::LRW32), CSKY::R28)
59104eeddc0SDimitry Andric       .addConstantPoolIndex(CPI)
59204eeddc0SDimitry Andric       .addMemOperand(MO);
59304eeddc0SDimitry Andric 
59404eeddc0SDimitry Andric   GlobalBaseReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);
59504eeddc0SDimitry Andric   BuildMI(FirstMBB, MBBI, DL, get(TargetOpcode::COPY), GlobalBaseReg)
59604eeddc0SDimitry Andric       .addReg(CSKY::R28);
59704eeddc0SDimitry Andric 
59804eeddc0SDimitry Andric   CFI->setGlobalBaseReg(GlobalBaseReg);
59904eeddc0SDimitry Andric   return GlobalBaseReg;
60004eeddc0SDimitry Andric }
60104eeddc0SDimitry Andric 
getInstSizeInBytes(const MachineInstr & MI) const60204eeddc0SDimitry Andric unsigned CSKYInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
60304eeddc0SDimitry Andric   switch (MI.getOpcode()) {
60404eeddc0SDimitry Andric   default:
60504eeddc0SDimitry Andric     return MI.getDesc().getSize();
60604eeddc0SDimitry Andric   case CSKY::CONSTPOOL_ENTRY:
60704eeddc0SDimitry Andric     return MI.getOperand(2).getImm();
60804eeddc0SDimitry Andric   case CSKY::SPILL_CARRY:
60904eeddc0SDimitry Andric   case CSKY::RESTORE_CARRY:
61004eeddc0SDimitry Andric   case CSKY::PseudoTLSLA32:
61104eeddc0SDimitry Andric     return 8;
61204eeddc0SDimitry Andric   case TargetOpcode::INLINEASM_BR:
61304eeddc0SDimitry Andric   case TargetOpcode::INLINEASM: {
61404eeddc0SDimitry Andric     const MachineFunction *MF = MI.getParent()->getParent();
61504eeddc0SDimitry Andric     const char *AsmStr = MI.getOperand(0).getSymbolName();
61604eeddc0SDimitry Andric     return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
61704eeddc0SDimitry Andric   }
61804eeddc0SDimitry Andric   }
61904eeddc0SDimitry Andric }
620