xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp (revision e6bfd18d21b225af6a0ed67ceeaf1293b7b9eba5)
1 //===-- CSKYInstrInfo.h - CSKY Instruction Information --------*- C++ -*---===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains the CSKY implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "CSKYInstrInfo.h"
14 #include "CSKYConstantPoolValue.h"
15 #include "CSKYMachineFunctionInfo.h"
16 #include "CSKYTargetMachine.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/MC/MCContext.h"
19 
20 #define DEBUG_TYPE "csky-instr-info"
21 
22 using namespace llvm;
23 
24 #define GET_INSTRINFO_CTOR_DTOR
25 #include "CSKYGenInstrInfo.inc"
26 
27 CSKYInstrInfo::CSKYInstrInfo(CSKYSubtarget &STI)
28     : CSKYGenInstrInfo(CSKY::ADJCALLSTACKDOWN, CSKY::ADJCALLSTACKUP), STI(STI) {
29   v2sf = STI.hasFPUv2SingleFloat();
30   v2df = STI.hasFPUv2DoubleFloat();
31   v3sf = STI.hasFPUv3SingleFloat();
32   v3df = STI.hasFPUv3DoubleFloat();
33 }
34 
35 static void parseCondBranch(MachineInstr &LastInst, MachineBasicBlock *&Target,
36                             SmallVectorImpl<MachineOperand> &Cond) {
37   // Block ends with fall-through condbranch.
38   assert(LastInst.getDesc().isConditionalBranch() &&
39          "Unknown conditional branch");
40   Target = LastInst.getOperand(1).getMBB();
41   Cond.push_back(MachineOperand::CreateImm(LastInst.getOpcode()));
42   Cond.push_back(LastInst.getOperand(0));
43 }
44 
45 bool CSKYInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
46                                   MachineBasicBlock *&TBB,
47                                   MachineBasicBlock *&FBB,
48                                   SmallVectorImpl<MachineOperand> &Cond,
49                                   bool AllowModify) const {
50   TBB = FBB = nullptr;
51   Cond.clear();
52 
53   // If the block has no terminators, it just falls into the block after it.
54   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
55   if (I == MBB.end() || !isUnpredicatedTerminator(*I))
56     return false;
57 
58   // Count the number of terminators and find the first unconditional or
59   // indirect branch.
60   MachineBasicBlock::iterator FirstUncondOrIndirectBr = MBB.end();
61   int NumTerminators = 0;
62   for (auto J = I.getReverse(); J != MBB.rend() && isUnpredicatedTerminator(*J);
63        J++) {
64     NumTerminators++;
65     if (J->getDesc().isUnconditionalBranch() ||
66         J->getDesc().isIndirectBranch()) {
67       FirstUncondOrIndirectBr = J.getReverse();
68     }
69   }
70 
71   // If AllowModify is true, we can erase any terminators after
72   // FirstUncondOrIndirectBR.
73   if (AllowModify && FirstUncondOrIndirectBr != MBB.end()) {
74     while (std::next(FirstUncondOrIndirectBr) != MBB.end()) {
75       std::next(FirstUncondOrIndirectBr)->eraseFromParent();
76       NumTerminators--;
77     }
78     I = FirstUncondOrIndirectBr;
79   }
80 
81   // We can't handle blocks that end in an indirect branch.
82   if (I->getDesc().isIndirectBranch())
83     return true;
84 
85   // We can't handle blocks with more than 2 terminators.
86   if (NumTerminators > 2)
87     return true;
88 
89   // Handle a single unconditional branch.
90   if (NumTerminators == 1 && I->getDesc().isUnconditionalBranch()) {
91     TBB = getBranchDestBlock(*I);
92     return false;
93   }
94 
95   // Handle a single conditional branch.
96   if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
97     parseCondBranch(*I, TBB, Cond);
98     return false;
99   }
100 
101   // Handle a conditional branch followed by an unconditional branch.
102   if (NumTerminators == 2 && std::prev(I)->getDesc().isConditionalBranch() &&
103       I->getDesc().isUnconditionalBranch()) {
104     parseCondBranch(*std::prev(I), TBB, Cond);
105     FBB = getBranchDestBlock(*I);
106     return false;
107   }
108 
109   // Otherwise, we can't handle this.
110   return true;
111 }
112 
113 unsigned CSKYInstrInfo::removeBranch(MachineBasicBlock &MBB,
114                                      int *BytesRemoved) const {
115   if (BytesRemoved)
116     *BytesRemoved = 0;
117   MachineBasicBlock::iterator I = MBB.getLastNonDebugInstr();
118   if (I == MBB.end())
119     return 0;
120 
121   if (!I->getDesc().isUnconditionalBranch() &&
122       !I->getDesc().isConditionalBranch())
123     return 0;
124 
125   // Remove the branch.
126   if (BytesRemoved)
127     *BytesRemoved += getInstSizeInBytes(*I);
128   I->eraseFromParent();
129 
130   I = MBB.end();
131 
132   if (I == MBB.begin())
133     return 1;
134   --I;
135   if (!I->getDesc().isConditionalBranch())
136     return 1;
137 
138   // Remove the branch.
139   if (BytesRemoved)
140     *BytesRemoved += getInstSizeInBytes(*I);
141   I->eraseFromParent();
142   return 2;
143 }
144 
145 MachineBasicBlock *
146 CSKYInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
147   assert(MI.getDesc().isBranch() && "Unexpected opcode!");
148   // The branch target is always the last operand.
149   int NumOp = MI.getNumExplicitOperands();
150   assert(MI.getOperand(NumOp - 1).isMBB() && "Expected MBB!");
151   return MI.getOperand(NumOp - 1).getMBB();
152 }
153 
154 unsigned CSKYInstrInfo::insertBranch(
155     MachineBasicBlock &MBB, MachineBasicBlock *TBB, MachineBasicBlock *FBB,
156     ArrayRef<MachineOperand> Cond, const DebugLoc &DL, int *BytesAdded) const {
157   if (BytesAdded)
158     *BytesAdded = 0;
159 
160   // Shouldn't be a fall through.
161   assert(TBB && "insertBranch must not be told to insert a fallthrough");
162   assert((Cond.size() == 2 || Cond.size() == 0) &&
163          "CSKY branch conditions have two components!");
164 
165   // Unconditional branch.
166   if (Cond.empty()) {
167     MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(TBB);
168     if (BytesAdded)
169       *BytesAdded += getInstSizeInBytes(MI);
170     return 1;
171   }
172 
173   // Either a one or two-way conditional branch.
174   unsigned Opc = Cond[0].getImm();
175   MachineInstr &CondMI = *BuildMI(&MBB, DL, get(Opc)).add(Cond[1]).addMBB(TBB);
176   if (BytesAdded)
177     *BytesAdded += getInstSizeInBytes(CondMI);
178 
179   // One-way conditional branch.
180   if (!FBB)
181     return 1;
182 
183   // Two-way conditional branch.
184   MachineInstr &MI = *BuildMI(&MBB, DL, get(CSKY::BR32)).addMBB(FBB);
185   if (BytesAdded)
186     *BytesAdded += getInstSizeInBytes(MI);
187   return 2;
188 }
189 
190 static unsigned getOppositeBranchOpc(unsigned Opcode) {
191   switch (Opcode) {
192   default:
193     llvm_unreachable("Unknown conditional branch!");
194   case CSKY::BT32:
195     return CSKY::BF32;
196   case CSKY::BT16:
197     return CSKY::BF16;
198   case CSKY::BF32:
199     return CSKY::BT32;
200   case CSKY::BF16:
201     return CSKY::BT16;
202   case CSKY::BHZ32:
203     return CSKY::BLSZ32;
204   case CSKY::BHSZ32:
205     return CSKY::BLZ32;
206   case CSKY::BLZ32:
207     return CSKY::BHSZ32;
208   case CSKY::BLSZ32:
209     return CSKY::BHZ32;
210   case CSKY::BNEZ32:
211     return CSKY::BEZ32;
212   case CSKY::BEZ32:
213     return CSKY::BNEZ32;
214   }
215 }
216 
217 bool CSKYInstrInfo::reverseBranchCondition(
218     SmallVectorImpl<MachineOperand> &Cond) const {
219   assert((Cond.size() == 2) && "Invalid branch condition!");
220   Cond[0].setImm(getOppositeBranchOpc(Cond[0].getImm()));
221   return false;
222 }
223 
224 Register CSKYInstrInfo::movImm(MachineBasicBlock &MBB,
225                                MachineBasicBlock::iterator MBBI,
226                                const DebugLoc &DL, uint64_t Val,
227                                MachineInstr::MIFlag Flag) const {
228   if (!isInt<32>(Val))
229     report_fatal_error("Should only materialize 32-bit constants.");
230 
231   MachineRegisterInfo &MRI = MBB.getParent()->getRegInfo();
232 
233   Register DstReg;
234   if (STI.hasE2()) {
235     DstReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);
236 
237     if (isUInt<16>(Val)) {
238       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI32), DstReg)
239           .addImm(Val & 0xFFFF)
240           .setMIFlags(Flag);
241     } else if (isShiftedUInt<16, 16>(Val)) {
242       BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg)
243           .addImm((Val >> 16) & 0xFFFF)
244           .setMIFlags(Flag);
245     } else {
246       BuildMI(MBB, MBBI, DL, get(CSKY::MOVIH32), DstReg)
247           .addImm((Val >> 16) & 0xFFFF)
248           .setMIFlags(Flag);
249       BuildMI(MBB, MBBI, DL, get(CSKY::ORI32), DstReg)
250           .addReg(DstReg)
251           .addImm(Val & 0xFFFF)
252           .setMIFlags(Flag);
253     }
254 
255   } else {
256     DstReg = MRI.createVirtualRegister(&CSKY::mGPRRegClass);
257     if (isUInt<8>(Val)) {
258       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
259           .addImm(Val & 0xFF)
260           .setMIFlags(Flag);
261     } else if (isUInt<16>(Val)) {
262       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
263           .addImm((Val >> 8) & 0xFF)
264           .setMIFlags(Flag);
265       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
266           .addReg(DstReg)
267           .addImm(8)
268           .setMIFlags(Flag);
269       if ((Val & 0xFF) != 0)
270         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
271             .addReg(DstReg)
272             .addImm(Val & 0xFF)
273             .setMIFlags(Flag);
274     } else if (isUInt<24>(Val)) {
275       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
276           .addImm((Val >> 16) & 0xFF)
277           .setMIFlags(Flag);
278       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
279           .addReg(DstReg)
280           .addImm(8)
281           .setMIFlags(Flag);
282       if (((Val >> 8) & 0xFF) != 0)
283         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
284             .addReg(DstReg)
285             .addImm((Val >> 8) & 0xFF)
286             .setMIFlags(Flag);
287       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
288           .addReg(DstReg)
289           .addImm(8)
290           .setMIFlags(Flag);
291       if ((Val & 0xFF) != 0)
292         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
293             .addReg(DstReg)
294             .addImm(Val & 0xFF)
295             .setMIFlags(Flag);
296     } else {
297       BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
298           .addImm((Val >> 24) & 0xFF)
299           .setMIFlags(Flag);
300       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
301           .addReg(DstReg)
302           .addImm(8)
303           .setMIFlags(Flag);
304       if (((Val >> 16) & 0xFF) != 0)
305         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
306             .addReg(DstReg)
307             .addImm((Val >> 16) & 0xFF)
308             .setMIFlags(Flag);
309       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
310           .addReg(DstReg)
311           .addImm(8)
312           .setMIFlags(Flag);
313       if (((Val >> 8) & 0xFF) != 0)
314         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
315             .addReg(DstReg)
316             .addImm((Val >> 8) & 0xFF)
317             .setMIFlags(Flag);
318       BuildMI(MBB, MBBI, DL, get(CSKY::LSLI16), DstReg)
319           .addReg(DstReg)
320           .addImm(8)
321           .setMIFlags(Flag);
322       if ((Val & 0xFF) != 0)
323         BuildMI(MBB, MBBI, DL, get(CSKY::ADDI16), DstReg)
324             .addReg(DstReg)
325             .addImm(Val & 0xFF)
326             .setMIFlags(Flag);
327     }
328   }
329 
330   return DstReg;
331 }
332 
333 unsigned CSKYInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
334                                             int &FrameIndex) const {
335   switch (MI.getOpcode()) {
336   default:
337     return 0;
338   case CSKY::LD16B:
339   case CSKY::LD16H:
340   case CSKY::LD16W:
341   case CSKY::LD32B:
342   case CSKY::LD32BS:
343   case CSKY::LD32H:
344   case CSKY::LD32HS:
345   case CSKY::LD32W:
346   case CSKY::FLD_S:
347   case CSKY::FLD_D:
348   case CSKY::f2FLD_S:
349   case CSKY::f2FLD_D:
350   case CSKY::RESTORE_CARRY:
351     break;
352   }
353 
354   if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
355       MI.getOperand(2).getImm() == 0) {
356     FrameIndex = MI.getOperand(1).getIndex();
357     return MI.getOperand(0).getReg();
358   }
359 
360   return 0;
361 }
362 
363 unsigned CSKYInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
364                                            int &FrameIndex) const {
365   switch (MI.getOpcode()) {
366   default:
367     return 0;
368   case CSKY::ST16B:
369   case CSKY::ST16H:
370   case CSKY::ST16W:
371   case CSKY::ST32B:
372   case CSKY::ST32H:
373   case CSKY::ST32W:
374   case CSKY::FST_S:
375   case CSKY::FST_D:
376   case CSKY::f2FST_S:
377   case CSKY::f2FST_D:
378   case CSKY::SPILL_CARRY:
379     break;
380   }
381 
382   if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
383       MI.getOperand(2).getImm() == 0) {
384     FrameIndex = MI.getOperand(1).getIndex();
385     return MI.getOperand(0).getReg();
386   }
387 
388   return 0;
389 }
390 
391 void CSKYInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
392                                         MachineBasicBlock::iterator I,
393                                         Register SrcReg, bool IsKill, int FI,
394                                         const TargetRegisterClass *RC,
395                                         const TargetRegisterInfo *TRI) const {
396   DebugLoc DL;
397   if (I != MBB.end())
398     DL = I->getDebugLoc();
399 
400   MachineFunction &MF = *MBB.getParent();
401   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
402   MachineFrameInfo &MFI = MF.getFrameInfo();
403 
404   unsigned Opcode = 0;
405 
406   if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
407     Opcode = CSKY::ST32W; // Optimize for 16bit
408   } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
409     Opcode = CSKY::SPILL_CARRY;
410     CFI->setSpillsCR();
411   } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
412     Opcode = CSKY::FST_S;
413   else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
414     Opcode = CSKY::FST_D;
415   else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
416     Opcode = CSKY::f2FST_S;
417   else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
418     Opcode = CSKY::f2FST_D;
419   else {
420     llvm_unreachable("Unknown RegisterClass");
421   }
422 
423   MachineMemOperand *MMO = MF.getMachineMemOperand(
424       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
425       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
426 
427   BuildMI(MBB, I, DL, get(Opcode))
428       .addReg(SrcReg, getKillRegState(IsKill))
429       .addFrameIndex(FI)
430       .addImm(0)
431       .addMemOperand(MMO);
432 }
433 
434 void CSKYInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
435                                          MachineBasicBlock::iterator I,
436                                          Register DestReg, int FI,
437                                          const TargetRegisterClass *RC,
438                                          const TargetRegisterInfo *TRI) const {
439   DebugLoc DL;
440   if (I != MBB.end())
441     DL = I->getDebugLoc();
442 
443   MachineFunction &MF = *MBB.getParent();
444   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
445   MachineFrameInfo &MFI = MF.getFrameInfo();
446 
447   unsigned Opcode = 0;
448 
449   if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
450     Opcode = CSKY::LD32W;
451   } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
452     Opcode = CSKY::RESTORE_CARRY;
453     CFI->setSpillsCR();
454   } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
455     Opcode = CSKY::FLD_S;
456   else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
457     Opcode = CSKY::FLD_D;
458   else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
459     Opcode = CSKY::f2FLD_S;
460   else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
461     Opcode = CSKY::f2FLD_D;
462   else {
463     llvm_unreachable("Unknown RegisterClass");
464   }
465 
466   MachineMemOperand *MMO = MF.getMachineMemOperand(
467       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
468       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
469 
470   BuildMI(MBB, I, DL, get(Opcode), DestReg)
471       .addFrameIndex(FI)
472       .addImm(0)
473       .addMemOperand(MMO);
474 }
475 
476 void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
477                                 MachineBasicBlock::iterator I,
478                                 const DebugLoc &DL, MCRegister DestReg,
479                                 MCRegister SrcReg, bool KillSrc) const {
480   if (CSKY::GPRRegClass.contains(SrcReg) &&
481       CSKY::CARRYRegClass.contains(DestReg)) {
482     if (STI.hasE2()) {
483       BuildMI(MBB, I, DL, get(CSKY::BTSTI32), DestReg)
484           .addReg(SrcReg, getKillRegState(KillSrc))
485           .addImm(0);
486     } else {
487       assert(SrcReg < CSKY::R8);
488       BuildMI(MBB, I, DL, get(CSKY::BTSTI16), DestReg)
489           .addReg(SrcReg, getKillRegState(KillSrc))
490           .addImm(0);
491     }
492     return;
493   }
494 
495   if (CSKY::CARRYRegClass.contains(SrcReg) &&
496       CSKY::GPRRegClass.contains(DestReg)) {
497 
498     if (STI.hasE2()) {
499       BuildMI(MBB, I, DL, get(CSKY::MVC32), DestReg)
500           .addReg(SrcReg, getKillRegState(KillSrc));
501     } else {
502       assert(DestReg < CSKY::R16);
503       assert(DestReg < CSKY::R8);
504       BuildMI(MBB, I, DL, get(CSKY::MOVI16), DestReg).addImm(0);
505       BuildMI(MBB, I, DL, get(CSKY::ADDC16))
506           .addReg(DestReg, RegState::Define)
507           .addReg(SrcReg, RegState::Define)
508           .addReg(DestReg, getKillRegState(true))
509           .addReg(DestReg, getKillRegState(true))
510           .addReg(SrcReg, getKillRegState(true));
511       BuildMI(MBB, I, DL, get(CSKY::BTSTI16))
512           .addReg(SrcReg, RegState::Define | getDeadRegState(KillSrc))
513           .addReg(DestReg)
514           .addImm(0);
515     }
516     return;
517   }
518 
519   unsigned Opcode = 0;
520   if (CSKY::GPRRegClass.contains(DestReg, SrcReg))
521     Opcode = STI.hasE2() ? CSKY::MOV32 : CSKY::MOV16;
522   else if (v2sf && CSKY::sFPR32RegClass.contains(DestReg, SrcReg))
523     Opcode = CSKY::FMOV_S;
524   else if (v3sf && CSKY::FPR32RegClass.contains(DestReg, SrcReg))
525     Opcode = CSKY::f2FMOV_S;
526   else if (v2df && CSKY::sFPR64RegClass.contains(DestReg, SrcReg))
527     Opcode = CSKY::FMOV_D;
528   else if (v3df && CSKY::FPR64RegClass.contains(DestReg, SrcReg))
529     Opcode = CSKY::f2FMOV_D;
530   else if (v2sf && CSKY::sFPR32RegClass.contains(SrcReg) &&
531            CSKY::GPRRegClass.contains(DestReg))
532     Opcode = CSKY::FMFVRL;
533   else if (v3sf && CSKY::FPR32RegClass.contains(SrcReg) &&
534            CSKY::GPRRegClass.contains(DestReg))
535     Opcode = CSKY::f2FMFVRL;
536   else if (v2df && CSKY::sFPR64RegClass.contains(SrcReg) &&
537            CSKY::GPRRegClass.contains(DestReg))
538     Opcode = CSKY::FMFVRL_D;
539   else if (v3df && CSKY::FPR64RegClass.contains(SrcReg) &&
540            CSKY::GPRRegClass.contains(DestReg))
541     Opcode = CSKY::f2FMFVRL_D;
542   else if (v2sf && CSKY::GPRRegClass.contains(SrcReg) &&
543            CSKY::sFPR32RegClass.contains(DestReg))
544     Opcode = CSKY::FMTVRL;
545   else if (v3sf && CSKY::GPRRegClass.contains(SrcReg) &&
546            CSKY::FPR32RegClass.contains(DestReg))
547     Opcode = CSKY::f2FMTVRL;
548   else if (v2df && CSKY::GPRRegClass.contains(SrcReg) &&
549            CSKY::sFPR64RegClass.contains(DestReg))
550     Opcode = CSKY::FMTVRL_D;
551   else if (v3df && CSKY::GPRRegClass.contains(SrcReg) &&
552            CSKY::FPR64RegClass.contains(DestReg))
553     Opcode = CSKY::f2FMTVRL_D;
554   else {
555     LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg);
556     LLVM_DEBUG(I->dump());
557     llvm_unreachable("Unknown RegisterClass");
558   }
559 
560   BuildMI(MBB, I, DL, get(Opcode), DestReg)
561       .addReg(SrcReg, getKillRegState(KillSrc));
562 }
563 
564 Register CSKYInstrInfo::getGlobalBaseReg(MachineFunction &MF) const {
565   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
566   MachineConstantPool *MCP = MF.getConstantPool();
567   MachineRegisterInfo &MRI = MF.getRegInfo();
568 
569   Register GlobalBaseReg = CFI->getGlobalBaseReg();
570   if (GlobalBaseReg != 0)
571     return GlobalBaseReg;
572 
573   // Insert a pseudo instruction to set the GlobalBaseReg into the first
574   // MBB of the function
575   MachineBasicBlock &FirstMBB = MF.front();
576   MachineBasicBlock::iterator MBBI = FirstMBB.begin();
577   DebugLoc DL;
578 
579   CSKYConstantPoolValue *CPV = CSKYConstantPoolSymbol::Create(
580       Type::getInt32Ty(MF.getFunction().getContext()), "_GLOBAL_OFFSET_TABLE_",
581       0, CSKYCP::ADDR);
582 
583   unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));
584 
585   MachineMemOperand *MO =
586       MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
587                               MachineMemOperand::MOLoad, 4, Align(4));
588   BuildMI(FirstMBB, MBBI, DL, get(CSKY::LRW32), CSKY::R28)
589       .addConstantPoolIndex(CPI)
590       .addMemOperand(MO);
591 
592   GlobalBaseReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);
593   BuildMI(FirstMBB, MBBI, DL, get(TargetOpcode::COPY), GlobalBaseReg)
594       .addReg(CSKY::R28);
595 
596   CFI->setGlobalBaseReg(GlobalBaseReg);
597   return GlobalBaseReg;
598 }
599 
600 unsigned CSKYInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
601   switch (MI.getOpcode()) {
602   default:
603     return MI.getDesc().getSize();
604   case CSKY::CONSTPOOL_ENTRY:
605     return MI.getOperand(2).getImm();
606   case CSKY::SPILL_CARRY:
607   case CSKY::RESTORE_CARRY:
608   case CSKY::PseudoTLSLA32:
609     return 8;
610   case TargetOpcode::INLINEASM_BR:
611   case TargetOpcode::INLINEASM: {
612     const MachineFunction *MF = MI.getParent()->getParent();
613     const char *AsmStr = MI.getOperand(0).getSymbolName();
614     return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
615   }
616   }
617 }
618