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
22using namespace llvm;
23
24#define GET_INSTRINFO_CTOR_DTOR
25#include "CSKYGenInstrInfo.inc"
26
27CSKYInstrInfo::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
35static 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(i: 1).getMBB();
41 Cond.push_back(Elt: MachineOperand::CreateImm(Val: LastInst.getOpcode()));
42 Cond.push_back(Elt: LastInst.getOperand(i: 0));
43}
44
45bool 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(x: FirstUncondOrIndirectBr) != MBB.end()) {
75 std::next(x: 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(MI: *I);
92 return false;
93 }
94
95 // Handle a single conditional branch.
96 if (NumTerminators == 1 && I->getDesc().isConditionalBranch()) {
97 parseCondBranch(LastInst&: *I, Target&: TBB, Cond);
98 return false;
99 }
100
101 // Handle a conditional branch followed by an unconditional branch.
102 if (NumTerminators == 2 && std::prev(x: I)->getDesc().isConditionalBranch() &&
103 I->getDesc().isUnconditionalBranch()) {
104 parseCondBranch(LastInst&: *std::prev(x: I), Target&: TBB, Cond);
105 FBB = getBranchDestBlock(MI: *I);
106 return false;
107 }
108
109 // Otherwise, we can't handle this.
110 return true;
111}
112
113unsigned 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(MI: *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(MI: *I);
141 I->eraseFromParent();
142 return 2;
143}
144
145MachineBasicBlock *
146CSKYInstrInfo::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(i: NumOp - 1).getMBB();
152}
153
154unsigned 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(MI: 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
190static 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
217bool CSKYInstrInfo::reverseBranchCondition(
218 SmallVectorImpl<MachineOperand> &Cond) const {
219 assert((Cond.size() == 2) && "Invalid branch condition!");
220 Cond[0].setImm(getOppositeBranchOpc(Opcode: Cond[0].getImm()));
221 return false;
222}
223
224Register CSKYInstrInfo::movImm(MachineBasicBlock &MBB,
225 MachineBasicBlock::iterator MBBI,
226 const DebugLoc &DL, uint64_t Val,
227 MachineInstr::MIFlag Flag) const {
228 if (!isInt<32>(x: Val))
229 report_fatal_error(reason: "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>(x: Val)) {
238 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI32), DstReg)
239 .addImm(Val & 0xFFFF)
240 .setMIFlags(Flag);
241 } else if (isShiftedUInt<16, 16>(x: 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>(x: Val)) {
258 BuildMI(MBB, MBBI, DL, get(CSKY::MOVI16), DstReg)
259 .addImm(Val & 0xFF)
260 .setMIFlags(Flag);
261 } else if (isUInt<16>(x: 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>(x: 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
333Register 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(i: 1).isFI() && MI.getOperand(i: 2).isImm() &&
355 MI.getOperand(i: 2).getImm() == 0) {
356 FrameIndex = MI.getOperand(i: 1).getIndex();
357 return MI.getOperand(i: 0).getReg();
358 }
359
360 return 0;
361}
362
363Register 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(i: 1).isFI() && MI.getOperand(i: 2).isImm() &&
383 MI.getOperand(i: 2).getImm() == 0) {
384 FrameIndex = MI.getOperand(i: 1).getIndex();
385 return MI.getOperand(i: 0).getReg();
386 }
387
388 return 0;
389}
390
391void 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 PtrInfo: MachinePointerInfo::getFixedStack(MF, FI), F: MachineMemOperand::MOStore,
426 Size: MFI.getObjectSize(ObjectIdx: FI), BaseAlignment: MFI.getObjectAlign(ObjectIdx: FI));
427
428 BuildMI(MBB, I, DL, get(Opcode))
429 .addReg(SrcReg, getKillRegState(B: IsKill))
430 .addFrameIndex(FI)
431 .addImm(0)
432 .addMemOperand(MMO);
433}
434
435void 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 PtrInfo: MachinePointerInfo::getFixedStack(MF, FI), F: MachineMemOperand::MOLoad,
470 Size: MFI.getObjectSize(ObjectIdx: FI), BaseAlignment: MFI.getObjectAlign(ObjectIdx: FI));
471
472 BuildMI(MBB, I, DL, get(Opcode), DestReg)
473 .addFrameIndex(FI)
474 .addImm(0)
475 .addMemOperand(MMO);
476}
477
478void 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(B: KillSrc));
564}
565
566Register 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 Ty: Type::getInt32Ty(C&: MF.getFunction().getContext()), S: "_GLOBAL_OFFSET_TABLE_",
583 PCAdjust: 0, Modifier: CSKYCP::ADDR);
584
585 unsigned CPI = MCP->getConstantPoolIndex(V: CPV, Alignment: Align(4));
586
587 MachineMemOperand *MO =
588 MF.getMachineMemOperand(PtrInfo: MachinePointerInfo::getConstantPool(MF),
589 F: MachineMemOperand::MOLoad, Size: 4, BaseAlignment: 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
602unsigned 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(i: 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(i: 0).getSymbolName();
616 return getInlineAsmLength(AsmStr, *MF->getTarget().getMCAsmInfo());
617 }
618 }
619}
620

source code of llvm/lib/Target/CSKY/CSKYInstrInfo.cpp