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
CSKYInstrInfo(CSKYSubtarget & STI)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
parseCondBranch(MachineInstr & LastInst,MachineBasicBlock * & Target,SmallVectorImpl<MachineOperand> & Cond)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
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const45 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
removeBranch(MachineBasicBlock & MBB,int * BytesRemoved) const113 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 *
getBranchDestBlock(const MachineInstr & MI) const146 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
insertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL,int * BytesAdded) const154 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
getOppositeBranchOpc(unsigned Opcode)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
reverseBranchCondition(SmallVectorImpl<MachineOperand> & Cond) const217 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
movImm(MachineBasicBlock & MBB,MachineBasicBlock::iterator MBBI,const DebugLoc & DL,uint64_t Val,MachineInstr::MIFlag Flag) const224 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
isLoadFromStackSlot(const MachineInstr & MI,int & FrameIndex) const333 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
isStoreToStackSlot(const MachineInstr & MI,int & FrameIndex) const363 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
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,Register SrcReg,bool IsKill,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const391 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
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,Register DestReg,int FI,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const434 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
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,const DebugLoc & DL,MCRegister DestReg,MCRegister SrcReg,bool KillSrc) const476 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
getGlobalBaseReg(MachineFunction & MF) const564 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
getInstSizeInBytes(const MachineInstr & MI) const600 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