xref: /freebsd/contrib/llvm-project/llvm/lib/Target/CSKY/CSKYInstrInfo.cpp (revision 7fdf597e96a02165cfe22ff357b857d5fa15ed8a)
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 Register 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 Register 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,
396                                         Register VReg) const {
397   DebugLoc DL;
398   if (I != MBB.end())
399     DL = I->getDebugLoc();
400 
401   MachineFunction &MF = *MBB.getParent();
402   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
403   MachineFrameInfo &MFI = MF.getFrameInfo();
404 
405   unsigned Opcode = 0;
406 
407   if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
408     Opcode = CSKY::ST32W; // Optimize for 16bit
409   } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
410     Opcode = CSKY::SPILL_CARRY;
411     CFI->setSpillsCR();
412   } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
413     Opcode = CSKY::FST_S;
414   else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
415     Opcode = CSKY::FST_D;
416   else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
417     Opcode = CSKY::f2FST_S;
418   else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
419     Opcode = CSKY::f2FST_D;
420   else {
421     llvm_unreachable("Unknown RegisterClass");
422   }
423 
424   MachineMemOperand *MMO = MF.getMachineMemOperand(
425       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOStore,
426       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
427 
428   BuildMI(MBB, I, DL, get(Opcode))
429       .addReg(SrcReg, getKillRegState(IsKill))
430       .addFrameIndex(FI)
431       .addImm(0)
432       .addMemOperand(MMO);
433 }
434 
435 void CSKYInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
436                                          MachineBasicBlock::iterator I,
437                                          Register DestReg, int FI,
438                                          const TargetRegisterClass *RC,
439                                          const TargetRegisterInfo *TRI,
440                                          Register VReg) const {
441   DebugLoc DL;
442   if (I != MBB.end())
443     DL = I->getDebugLoc();
444 
445   MachineFunction &MF = *MBB.getParent();
446   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
447   MachineFrameInfo &MFI = MF.getFrameInfo();
448 
449   unsigned Opcode = 0;
450 
451   if (CSKY::GPRRegClass.hasSubClassEq(RC)) {
452     Opcode = CSKY::LD32W;
453   } else if (CSKY::CARRYRegClass.hasSubClassEq(RC)) {
454     Opcode = CSKY::RESTORE_CARRY;
455     CFI->setSpillsCR();
456   } else if (v2sf && CSKY::sFPR32RegClass.hasSubClassEq(RC))
457     Opcode = CSKY::FLD_S;
458   else if (v2df && CSKY::sFPR64RegClass.hasSubClassEq(RC))
459     Opcode = CSKY::FLD_D;
460   else if (v3sf && CSKY::FPR32RegClass.hasSubClassEq(RC))
461     Opcode = CSKY::f2FLD_S;
462   else if (v3df && CSKY::FPR64RegClass.hasSubClassEq(RC))
463     Opcode = CSKY::f2FLD_D;
464   else {
465     llvm_unreachable("Unknown RegisterClass");
466   }
467 
468   MachineMemOperand *MMO = MF.getMachineMemOperand(
469       MachinePointerInfo::getFixedStack(MF, FI), MachineMemOperand::MOLoad,
470       MFI.getObjectSize(FI), MFI.getObjectAlign(FI));
471 
472   BuildMI(MBB, I, DL, get(Opcode), DestReg)
473       .addFrameIndex(FI)
474       .addImm(0)
475       .addMemOperand(MMO);
476 }
477 
478 void CSKYInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
479                                 MachineBasicBlock::iterator I,
480                                 const DebugLoc &DL, MCRegister DestReg,
481                                 MCRegister SrcReg, bool KillSrc) const {
482   if (CSKY::GPRRegClass.contains(SrcReg) &&
483       CSKY::CARRYRegClass.contains(DestReg)) {
484     if (STI.hasE2()) {
485       BuildMI(MBB, I, DL, get(CSKY::BTSTI32), DestReg)
486           .addReg(SrcReg, getKillRegState(KillSrc))
487           .addImm(0);
488     } else {
489       assert(SrcReg < CSKY::R8);
490       BuildMI(MBB, I, DL, get(CSKY::BTSTI16), DestReg)
491           .addReg(SrcReg, getKillRegState(KillSrc))
492           .addImm(0);
493     }
494     return;
495   }
496 
497   if (CSKY::CARRYRegClass.contains(SrcReg) &&
498       CSKY::GPRRegClass.contains(DestReg)) {
499 
500     if (STI.hasE2()) {
501       BuildMI(MBB, I, DL, get(CSKY::MVC32), DestReg)
502           .addReg(SrcReg, getKillRegState(KillSrc));
503     } else {
504       assert(DestReg < CSKY::R16);
505       assert(DestReg < CSKY::R8);
506       BuildMI(MBB, I, DL, get(CSKY::MOVI16), DestReg).addImm(0);
507       BuildMI(MBB, I, DL, get(CSKY::ADDC16))
508           .addReg(DestReg, RegState::Define)
509           .addReg(SrcReg, RegState::Define)
510           .addReg(DestReg, getKillRegState(true))
511           .addReg(DestReg, getKillRegState(true))
512           .addReg(SrcReg, getKillRegState(true));
513       BuildMI(MBB, I, DL, get(CSKY::BTSTI16))
514           .addReg(SrcReg, RegState::Define | getDeadRegState(KillSrc))
515           .addReg(DestReg)
516           .addImm(0);
517     }
518     return;
519   }
520 
521   unsigned Opcode = 0;
522   if (CSKY::GPRRegClass.contains(DestReg, SrcReg))
523     Opcode = STI.hasE2() ? CSKY::MOV32 : CSKY::MOV16;
524   else if (v2sf && CSKY::sFPR32RegClass.contains(DestReg, SrcReg))
525     Opcode = CSKY::FMOV_S;
526   else if (v3sf && CSKY::FPR32RegClass.contains(DestReg, SrcReg))
527     Opcode = CSKY::f2FMOV_S;
528   else if (v2df && CSKY::sFPR64RegClass.contains(DestReg, SrcReg))
529     Opcode = CSKY::FMOV_D;
530   else if (v3df && CSKY::FPR64RegClass.contains(DestReg, SrcReg))
531     Opcode = CSKY::f2FMOV_D;
532   else if (v2sf && CSKY::sFPR32RegClass.contains(SrcReg) &&
533            CSKY::GPRRegClass.contains(DestReg))
534     Opcode = CSKY::FMFVRL;
535   else if (v3sf && CSKY::FPR32RegClass.contains(SrcReg) &&
536            CSKY::GPRRegClass.contains(DestReg))
537     Opcode = CSKY::f2FMFVRL;
538   else if (v2df && CSKY::sFPR64RegClass.contains(SrcReg) &&
539            CSKY::GPRRegClass.contains(DestReg))
540     Opcode = CSKY::FMFVRL_D;
541   else if (v3df && CSKY::FPR64RegClass.contains(SrcReg) &&
542            CSKY::GPRRegClass.contains(DestReg))
543     Opcode = CSKY::f2FMFVRL_D;
544   else if (v2sf && CSKY::GPRRegClass.contains(SrcReg) &&
545            CSKY::sFPR32RegClass.contains(DestReg))
546     Opcode = CSKY::FMTVRL;
547   else if (v3sf && CSKY::GPRRegClass.contains(SrcReg) &&
548            CSKY::FPR32RegClass.contains(DestReg))
549     Opcode = CSKY::f2FMTVRL;
550   else if (v2df && CSKY::GPRRegClass.contains(SrcReg) &&
551            CSKY::sFPR64RegClass.contains(DestReg))
552     Opcode = CSKY::FMTVRL_D;
553   else if (v3df && CSKY::GPRRegClass.contains(SrcReg) &&
554            CSKY::FPR64RegClass.contains(DestReg))
555     Opcode = CSKY::f2FMTVRL_D;
556   else {
557     LLVM_DEBUG(dbgs() << "src = " << SrcReg << ", dst = " << DestReg);
558     LLVM_DEBUG(I->dump());
559     llvm_unreachable("Unknown RegisterClass");
560   }
561 
562   BuildMI(MBB, I, DL, get(Opcode), DestReg)
563       .addReg(SrcReg, getKillRegState(KillSrc));
564 }
565 
566 Register CSKYInstrInfo::getGlobalBaseReg(MachineFunction &MF) const {
567   CSKYMachineFunctionInfo *CFI = MF.getInfo<CSKYMachineFunctionInfo>();
568   MachineConstantPool *MCP = MF.getConstantPool();
569   MachineRegisterInfo &MRI = MF.getRegInfo();
570 
571   Register GlobalBaseReg = CFI->getGlobalBaseReg();
572   if (GlobalBaseReg != 0)
573     return GlobalBaseReg;
574 
575   // Insert a pseudo instruction to set the GlobalBaseReg into the first
576   // MBB of the function
577   MachineBasicBlock &FirstMBB = MF.front();
578   MachineBasicBlock::iterator MBBI = FirstMBB.begin();
579   DebugLoc DL;
580 
581   CSKYConstantPoolValue *CPV = CSKYConstantPoolSymbol::Create(
582       Type::getInt32Ty(MF.getFunction().getContext()), "_GLOBAL_OFFSET_TABLE_",
583       0, CSKYCP::ADDR);
584 
585   unsigned CPI = MCP->getConstantPoolIndex(CPV, Align(4));
586 
587   MachineMemOperand *MO =
588       MF.getMachineMemOperand(MachinePointerInfo::getConstantPool(MF),
589                               MachineMemOperand::MOLoad, 4, Align(4));
590   BuildMI(FirstMBB, MBBI, DL, get(CSKY::LRW32), CSKY::R28)
591       .addConstantPoolIndex(CPI)
592       .addMemOperand(MO);
593 
594   GlobalBaseReg = MRI.createVirtualRegister(&CSKY::GPRRegClass);
595   BuildMI(FirstMBB, MBBI, DL, get(TargetOpcode::COPY), GlobalBaseReg)
596       .addReg(CSKY::R28);
597 
598   CFI->setGlobalBaseReg(GlobalBaseReg);
599   return GlobalBaseReg;
600 }
601 
602 unsigned CSKYInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
603   switch (MI.getOpcode()) {
604   default:
605     return MI.getDesc().getSize();
606   case CSKY::CONSTPOOL_ENTRY:
607     return MI.getOperand(2).getImm();
608   case CSKY::SPILL_CARRY:
609   case CSKY::RESTORE_CARRY:
610   case CSKY::PseudoTLSLA32:
611     return 8;
612   case TargetOpcode::INLINEASM_BR:
613   case TargetOpcode::INLINEASM: {
614     const MachineFunction *MF = MI.getParent()->getParent();
615     const char *AsmStr = MI.getOperand(0).getSymbolName();
616     return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
617   }
618   }
619 }
620