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