120
|
1 //===-- AVRInstrInfo.cpp - AVR Instruction Information --------------------===//
|
|
2 //
|
147
|
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
|
120
|
6 //
|
|
7 //===----------------------------------------------------------------------===//
|
|
8 //
|
|
9 // This file contains the AVR implementation of the TargetInstrInfo class.
|
|
10 //
|
|
11 //===----------------------------------------------------------------------===//
|
|
12
|
|
13 #include "AVRInstrInfo.h"
|
|
14
|
|
15 #include "llvm/ADT/STLExtras.h"
|
|
16 #include "llvm/CodeGen/MachineConstantPool.h"
|
|
17 #include "llvm/CodeGen/MachineFrameInfo.h"
|
|
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
|
|
19 #include "llvm/CodeGen/MachineMemOperand.h"
|
|
20 #include "llvm/IR/Constants.h"
|
|
21 #include "llvm/IR/Function.h"
|
|
22 #include "llvm/MC/MCContext.h"
|
|
23 #include "llvm/Support/Debug.h"
|
|
24 #include "llvm/Support/ErrorHandling.h"
|
|
25 #include "llvm/Support/TargetRegistry.h"
|
|
26
|
|
27 #include "AVR.h"
|
|
28 #include "AVRMachineFunctionInfo.h"
|
|
29 #include "AVRRegisterInfo.h"
|
|
30 #include "AVRTargetMachine.h"
|
|
31 #include "MCTargetDesc/AVRMCTargetDesc.h"
|
|
32
|
|
33 #define GET_INSTRINFO_CTOR_DTOR
|
|
34 #include "AVRGenInstrInfo.inc"
|
|
35
|
|
36 namespace llvm {
|
|
37
|
|
38 AVRInstrInfo::AVRInstrInfo()
|
|
39 : AVRGenInstrInfo(AVR::ADJCALLSTACKDOWN, AVR::ADJCALLSTACKUP), RI() {}
|
|
40
|
|
41 void AVRInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
|
|
42 MachineBasicBlock::iterator MI,
|
|
43 const DebugLoc &DL, unsigned DestReg,
|
|
44 unsigned SrcReg, bool KillSrc) const {
|
|
45 const AVRSubtarget &STI = MBB.getParent()->getSubtarget<AVRSubtarget>();
|
|
46 const AVRRegisterInfo &TRI = *STI.getRegisterInfo();
|
|
47 unsigned Opc;
|
|
48
|
|
49 // Not all AVR devices support the 16-bit `MOVW` instruction.
|
|
50 if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) {
|
|
51 if (STI.hasMOVW()) {
|
|
52 BuildMI(MBB, MI, DL, get(AVR::MOVWRdRr), DestReg)
|
|
53 .addReg(SrcReg, getKillRegState(KillSrc));
|
|
54 } else {
|
|
55 unsigned DestLo, DestHi, SrcLo, SrcHi;
|
|
56
|
|
57 TRI.splitReg(DestReg, DestLo, DestHi);
|
|
58 TRI.splitReg(SrcReg, SrcLo, SrcHi);
|
|
59
|
|
60 // Copy each individual register with the `MOV` instruction.
|
|
61 BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestLo)
|
|
62 .addReg(SrcLo, getKillRegState(KillSrc));
|
|
63 BuildMI(MBB, MI, DL, get(AVR::MOVRdRr), DestHi)
|
|
64 .addReg(SrcHi, getKillRegState(KillSrc));
|
|
65 }
|
|
66 } else {
|
|
67 if (AVR::GPR8RegClass.contains(DestReg, SrcReg)) {
|
|
68 Opc = AVR::MOVRdRr;
|
|
69 } else if (SrcReg == AVR::SP && AVR::DREGSRegClass.contains(DestReg)) {
|
|
70 Opc = AVR::SPREAD;
|
|
71 } else if (DestReg == AVR::SP && AVR::DREGSRegClass.contains(SrcReg)) {
|
|
72 Opc = AVR::SPWRITE;
|
|
73 } else {
|
|
74 llvm_unreachable("Impossible reg-to-reg copy");
|
|
75 }
|
|
76
|
|
77 BuildMI(MBB, MI, DL, get(Opc), DestReg)
|
|
78 .addReg(SrcReg, getKillRegState(KillSrc));
|
|
79 }
|
|
80 }
|
|
81
|
|
82 unsigned AVRInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
|
|
83 int &FrameIndex) const {
|
|
84 switch (MI.getOpcode()) {
|
|
85 case AVR::LDDRdPtrQ:
|
|
86 case AVR::LDDWRdYQ: { //:FIXME: remove this once PR13375 gets fixed
|
|
87 if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
|
|
88 MI.getOperand(2).getImm() == 0) {
|
|
89 FrameIndex = MI.getOperand(1).getIndex();
|
|
90 return MI.getOperand(0).getReg();
|
|
91 }
|
|
92 break;
|
|
93 }
|
|
94 default:
|
|
95 break;
|
|
96 }
|
|
97
|
|
98 return 0;
|
|
99 }
|
|
100
|
|
101 unsigned AVRInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
|
|
102 int &FrameIndex) const {
|
|
103 switch (MI.getOpcode()) {
|
|
104 case AVR::STDPtrQRr:
|
|
105 case AVR::STDWPtrQRr: {
|
|
106 if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
|
|
107 MI.getOperand(1).getImm() == 0) {
|
|
108 FrameIndex = MI.getOperand(0).getIndex();
|
|
109 return MI.getOperand(2).getReg();
|
|
110 }
|
|
111 break;
|
|
112 }
|
|
113 default:
|
|
114 break;
|
|
115 }
|
|
116
|
|
117 return 0;
|
|
118 }
|
|
119
|
|
120 void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
|
|
121 MachineBasicBlock::iterator MI,
|
|
122 unsigned SrcReg, bool isKill,
|
|
123 int FrameIndex,
|
|
124 const TargetRegisterClass *RC,
|
|
125 const TargetRegisterInfo *TRI) const {
|
|
126 MachineFunction &MF = *MBB.getParent();
|
|
127 AVRMachineFunctionInfo *AFI = MF.getInfo<AVRMachineFunctionInfo>();
|
|
128
|
|
129 AFI->setHasSpills(true);
|
|
130
|
|
131 DebugLoc DL;
|
|
132 if (MI != MBB.end()) {
|
|
133 DL = MI->getDebugLoc();
|
|
134 }
|
|
135
|
|
136 const MachineFrameInfo &MFI = MF.getFrameInfo();
|
|
137
|
|
138 MachineMemOperand *MMO = MF.getMachineMemOperand(
|
|
139 MachinePointerInfo::getFixedStack(MF, FrameIndex),
|
|
140 MachineMemOperand::MOStore, MFI.getObjectSize(FrameIndex),
|
|
141 MFI.getObjectAlignment(FrameIndex));
|
|
142
|
|
143 unsigned Opcode = 0;
|
121
|
144 if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
|
120
|
145 Opcode = AVR::STDPtrQRr;
|
121
|
146 } else if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
|
120
|
147 Opcode = AVR::STDWPtrQRr;
|
|
148 } else {
|
|
149 llvm_unreachable("Cannot store this register into a stack slot!");
|
|
150 }
|
|
151
|
|
152 BuildMI(MBB, MI, DL, get(Opcode))
|
|
153 .addFrameIndex(FrameIndex)
|
|
154 .addImm(0)
|
|
155 .addReg(SrcReg, getKillRegState(isKill))
|
|
156 .addMemOperand(MMO);
|
|
157 }
|
|
158
|
|
159 void AVRInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
|
|
160 MachineBasicBlock::iterator MI,
|
|
161 unsigned DestReg, int FrameIndex,
|
|
162 const TargetRegisterClass *RC,
|
|
163 const TargetRegisterInfo *TRI) const {
|
|
164 DebugLoc DL;
|
|
165 if (MI != MBB.end()) {
|
|
166 DL = MI->getDebugLoc();
|
|
167 }
|
|
168
|
|
169 MachineFunction &MF = *MBB.getParent();
|
|
170 const MachineFrameInfo &MFI = MF.getFrameInfo();
|
|
171
|
|
172 MachineMemOperand *MMO = MF.getMachineMemOperand(
|
|
173 MachinePointerInfo::getFixedStack(MF, FrameIndex),
|
|
174 MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex),
|
|
175 MFI.getObjectAlignment(FrameIndex));
|
|
176
|
|
177 unsigned Opcode = 0;
|
121
|
178 if (TRI->isTypeLegalForClass(*RC, MVT::i8)) {
|
120
|
179 Opcode = AVR::LDDRdPtrQ;
|
121
|
180 } else if (TRI->isTypeLegalForClass(*RC, MVT::i16)) {
|
120
|
181 // Opcode = AVR::LDDWRdPtrQ;
|
|
182 //:FIXME: remove this once PR13375 gets fixed
|
|
183 Opcode = AVR::LDDWRdYQ;
|
|
184 } else {
|
|
185 llvm_unreachable("Cannot load this register from a stack slot!");
|
|
186 }
|
|
187
|
|
188 BuildMI(MBB, MI, DL, get(Opcode), DestReg)
|
|
189 .addFrameIndex(FrameIndex)
|
|
190 .addImm(0)
|
|
191 .addMemOperand(MMO);
|
|
192 }
|
|
193
|
|
194 const MCInstrDesc &AVRInstrInfo::getBrCond(AVRCC::CondCodes CC) const {
|
|
195 switch (CC) {
|
|
196 default:
|
|
197 llvm_unreachable("Unknown condition code!");
|
|
198 case AVRCC::COND_EQ:
|
|
199 return get(AVR::BREQk);
|
|
200 case AVRCC::COND_NE:
|
|
201 return get(AVR::BRNEk);
|
|
202 case AVRCC::COND_GE:
|
|
203 return get(AVR::BRGEk);
|
|
204 case AVRCC::COND_LT:
|
|
205 return get(AVR::BRLTk);
|
|
206 case AVRCC::COND_SH:
|
|
207 return get(AVR::BRSHk);
|
|
208 case AVRCC::COND_LO:
|
|
209 return get(AVR::BRLOk);
|
|
210 case AVRCC::COND_MI:
|
|
211 return get(AVR::BRMIk);
|
|
212 case AVRCC::COND_PL:
|
|
213 return get(AVR::BRPLk);
|
|
214 }
|
|
215 }
|
|
216
|
|
217 AVRCC::CondCodes AVRInstrInfo::getCondFromBranchOpc(unsigned Opc) const {
|
|
218 switch (Opc) {
|
|
219 default:
|
|
220 return AVRCC::COND_INVALID;
|
|
221 case AVR::BREQk:
|
|
222 return AVRCC::COND_EQ;
|
|
223 case AVR::BRNEk:
|
|
224 return AVRCC::COND_NE;
|
|
225 case AVR::BRSHk:
|
|
226 return AVRCC::COND_SH;
|
|
227 case AVR::BRLOk:
|
|
228 return AVRCC::COND_LO;
|
|
229 case AVR::BRMIk:
|
|
230 return AVRCC::COND_MI;
|
|
231 case AVR::BRPLk:
|
|
232 return AVRCC::COND_PL;
|
|
233 case AVR::BRGEk:
|
|
234 return AVRCC::COND_GE;
|
|
235 case AVR::BRLTk:
|
|
236 return AVRCC::COND_LT;
|
|
237 }
|
|
238 }
|
|
239
|
|
240 AVRCC::CondCodes AVRInstrInfo::getOppositeCondition(AVRCC::CondCodes CC) const {
|
|
241 switch (CC) {
|
|
242 default:
|
|
243 llvm_unreachable("Invalid condition!");
|
|
244 case AVRCC::COND_EQ:
|
|
245 return AVRCC::COND_NE;
|
|
246 case AVRCC::COND_NE:
|
|
247 return AVRCC::COND_EQ;
|
|
248 case AVRCC::COND_SH:
|
|
249 return AVRCC::COND_LO;
|
|
250 case AVRCC::COND_LO:
|
|
251 return AVRCC::COND_SH;
|
|
252 case AVRCC::COND_GE:
|
|
253 return AVRCC::COND_LT;
|
|
254 case AVRCC::COND_LT:
|
|
255 return AVRCC::COND_GE;
|
|
256 case AVRCC::COND_MI:
|
|
257 return AVRCC::COND_PL;
|
|
258 case AVRCC::COND_PL:
|
|
259 return AVRCC::COND_MI;
|
|
260 }
|
|
261 }
|
|
262
|
|
263 bool AVRInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
|
|
264 MachineBasicBlock *&TBB,
|
|
265 MachineBasicBlock *&FBB,
|
|
266 SmallVectorImpl<MachineOperand> &Cond,
|
|
267 bool AllowModify) const {
|
|
268 // Start from the bottom of the block and work up, examining the
|
|
269 // terminator instructions.
|
|
270 MachineBasicBlock::iterator I = MBB.end();
|
|
271 MachineBasicBlock::iterator UnCondBrIter = MBB.end();
|
|
272
|
|
273 while (I != MBB.begin()) {
|
|
274 --I;
|
147
|
275 if (I->isDebugInstr()) {
|
120
|
276 continue;
|
|
277 }
|
|
278
|
|
279 // Working from the bottom, when we see a non-terminator
|
|
280 // instruction, we're done.
|
|
281 if (!isUnpredicatedTerminator(*I)) {
|
|
282 break;
|
|
283 }
|
|
284
|
|
285 // A terminator that isn't a branch can't easily be handled
|
|
286 // by this analysis.
|
|
287 if (!I->getDesc().isBranch()) {
|
|
288 return true;
|
|
289 }
|
|
290
|
|
291 // Handle unconditional branches.
|
|
292 //:TODO: add here jmp
|
|
293 if (I->getOpcode() == AVR::RJMPk) {
|
|
294 UnCondBrIter = I;
|
|
295
|
|
296 if (!AllowModify) {
|
|
297 TBB = I->getOperand(0).getMBB();
|
|
298 continue;
|
|
299 }
|
|
300
|
|
301 // If the block has any instructions after a JMP, delete them.
|
|
302 while (std::next(I) != MBB.end()) {
|
|
303 std::next(I)->eraseFromParent();
|
|
304 }
|
|
305
|
|
306 Cond.clear();
|
|
307 FBB = 0;
|
|
308
|
|
309 // Delete the JMP if it's equivalent to a fall-through.
|
|
310 if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
|
|
311 TBB = 0;
|
|
312 I->eraseFromParent();
|
|
313 I = MBB.end();
|
|
314 UnCondBrIter = MBB.end();
|
|
315 continue;
|
|
316 }
|
|
317
|
|
318 // TBB is used to indicate the unconditinal destination.
|
|
319 TBB = I->getOperand(0).getMBB();
|
|
320 continue;
|
|
321 }
|
|
322
|
|
323 // Handle conditional branches.
|
|
324 AVRCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode());
|
|
325 if (BranchCode == AVRCC::COND_INVALID) {
|
|
326 return true; // Can't handle indirect branch.
|
|
327 }
|
|
328
|
|
329 // Working from the bottom, handle the first conditional branch.
|
|
330 if (Cond.empty()) {
|
|
331 MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
|
|
332 if (AllowModify && UnCondBrIter != MBB.end() &&
|
|
333 MBB.isLayoutSuccessor(TargetBB)) {
|
|
334 // If we can modify the code and it ends in something like:
|
|
335 //
|
|
336 // jCC L1
|
|
337 // jmp L2
|
|
338 // L1:
|
|
339 // ...
|
|
340 // L2:
|
|
341 //
|
|
342 // Then we can change this to:
|
|
343 //
|
|
344 // jnCC L2
|
|
345 // L1:
|
|
346 // ...
|
|
347 // L2:
|
|
348 //
|
|
349 // Which is a bit more efficient.
|
|
350 // We conditionally jump to the fall-through block.
|
|
351 BranchCode = getOppositeCondition(BranchCode);
|
|
352 unsigned JNCC = getBrCond(BranchCode).getOpcode();
|
|
353 MachineBasicBlock::iterator OldInst = I;
|
|
354
|
|
355 BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(JNCC))
|
|
356 .addMBB(UnCondBrIter->getOperand(0).getMBB());
|
|
357 BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(AVR::RJMPk))
|
|
358 .addMBB(TargetBB);
|
|
359
|
|
360 OldInst->eraseFromParent();
|
|
361 UnCondBrIter->eraseFromParent();
|
|
362
|
|
363 // Restart the analysis.
|
|
364 UnCondBrIter = MBB.end();
|
|
365 I = MBB.end();
|
|
366 continue;
|
|
367 }
|
|
368
|
|
369 FBB = TBB;
|
|
370 TBB = I->getOperand(0).getMBB();
|
|
371 Cond.push_back(MachineOperand::CreateImm(BranchCode));
|
|
372 continue;
|
|
373 }
|
|
374
|
|
375 // Handle subsequent conditional branches. Only handle the case where all
|
|
376 // conditional branches branch to the same destination.
|
|
377 assert(Cond.size() == 1);
|
|
378 assert(TBB);
|
|
379
|
|
380 // Only handle the case where all conditional branches branch to
|
|
381 // the same destination.
|
|
382 if (TBB != I->getOperand(0).getMBB()) {
|
|
383 return true;
|
|
384 }
|
|
385
|
|
386 AVRCC::CondCodes OldBranchCode = (AVRCC::CondCodes)Cond[0].getImm();
|
|
387 // If the conditions are the same, we can leave them alone.
|
|
388 if (OldBranchCode == BranchCode) {
|
|
389 continue;
|
|
390 }
|
|
391
|
|
392 return true;
|
|
393 }
|
|
394
|
|
395 return false;
|
|
396 }
|
|
397
|
|
398 unsigned AVRInstrInfo::insertBranch(MachineBasicBlock &MBB,
|
|
399 MachineBasicBlock *TBB,
|
|
400 MachineBasicBlock *FBB,
|
|
401 ArrayRef<MachineOperand> Cond,
|
|
402 const DebugLoc &DL,
|
|
403 int *BytesAdded) const {
|
121
|
404 if (BytesAdded) *BytesAdded = 0;
|
120
|
405
|
|
406 // Shouldn't be a fall through.
|
|
407 assert(TBB && "insertBranch must not be told to insert a fallthrough");
|
|
408 assert((Cond.size() == 1 || Cond.size() == 0) &&
|
|
409 "AVR branch conditions have one component!");
|
|
410
|
|
411 if (Cond.empty()) {
|
|
412 assert(!FBB && "Unconditional branch with multiple successors!");
|
121
|
413 auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
|
|
414 if (BytesAdded)
|
|
415 *BytesAdded += getInstSizeInBytes(MI);
|
120
|
416 return 1;
|
|
417 }
|
|
418
|
|
419 // Conditional branch.
|
|
420 unsigned Count = 0;
|
|
421 AVRCC::CondCodes CC = (AVRCC::CondCodes)Cond[0].getImm();
|
121
|
422 auto &CondMI = *BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
|
|
423
|
|
424 if (BytesAdded) *BytesAdded += getInstSizeInBytes(CondMI);
|
120
|
425 ++Count;
|
|
426
|
|
427 if (FBB) {
|
|
428 // Two-way Conditional branch. Insert the second branch.
|
121
|
429 auto &MI = *BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
|
|
430 if (BytesAdded) *BytesAdded += getInstSizeInBytes(MI);
|
120
|
431 ++Count;
|
|
432 }
|
|
433
|
|
434 return Count;
|
|
435 }
|
|
436
|
|
437 unsigned AVRInstrInfo::removeBranch(MachineBasicBlock &MBB,
|
|
438 int *BytesRemoved) const {
|
121
|
439 if (BytesRemoved) *BytesRemoved = 0;
|
120
|
440
|
|
441 MachineBasicBlock::iterator I = MBB.end();
|
|
442 unsigned Count = 0;
|
|
443
|
|
444 while (I != MBB.begin()) {
|
|
445 --I;
|
147
|
446 if (I->isDebugInstr()) {
|
120
|
447 continue;
|
|
448 }
|
|
449 //:TODO: add here the missing jmp instructions once they are implemented
|
|
450 // like jmp, {e}ijmp, and other cond branches, ...
|
|
451 if (I->getOpcode() != AVR::RJMPk &&
|
|
452 getCondFromBranchOpc(I->getOpcode()) == AVRCC::COND_INVALID) {
|
|
453 break;
|
|
454 }
|
|
455
|
|
456 // Remove the branch.
|
121
|
457 if (BytesRemoved) *BytesRemoved += getInstSizeInBytes(*I);
|
120
|
458 I->eraseFromParent();
|
|
459 I = MBB.end();
|
|
460 ++Count;
|
|
461 }
|
|
462
|
|
463 return Count;
|
|
464 }
|
|
465
|
|
466 bool AVRInstrInfo::reverseBranchCondition(
|
|
467 SmallVectorImpl<MachineOperand> &Cond) const {
|
|
468 assert(Cond.size() == 1 && "Invalid AVR branch condition!");
|
|
469
|
|
470 AVRCC::CondCodes CC = static_cast<AVRCC::CondCodes>(Cond[0].getImm());
|
|
471 Cond[0].setImm(getOppositeCondition(CC));
|
|
472
|
|
473 return false;
|
|
474 }
|
|
475
|
|
476 unsigned AVRInstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
|
|
477 unsigned Opcode = MI.getOpcode();
|
|
478
|
|
479 switch (Opcode) {
|
|
480 // A regular instruction
|
|
481 default: {
|
|
482 const MCInstrDesc &Desc = get(Opcode);
|
|
483 return Desc.getSize();
|
|
484 }
|
|
485 case TargetOpcode::EH_LABEL:
|
|
486 case TargetOpcode::IMPLICIT_DEF:
|
|
487 case TargetOpcode::KILL:
|
|
488 case TargetOpcode::DBG_VALUE:
|
|
489 return 0;
|
147
|
490 case TargetOpcode::INLINEASM:
|
|
491 case TargetOpcode::INLINEASM_BR: {
|
120
|
492 const MachineFunction &MF = *MI.getParent()->getParent();
|
|
493 const AVRTargetMachine &TM = static_cast<const AVRTargetMachine&>(MF.getTarget());
|
|
494 const AVRSubtarget &STI = MF.getSubtarget<AVRSubtarget>();
|
|
495 const TargetInstrInfo &TII = *STI.getInstrInfo();
|
|
496
|
|
497 return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
|
|
498 *TM.getMCAsmInfo());
|
|
499 }
|
|
500 }
|
|
501 }
|
|
502
|
121
|
503 MachineBasicBlock *
|
|
504 AVRInstrInfo::getBranchDestBlock(const MachineInstr &MI) const {
|
|
505 switch (MI.getOpcode()) {
|
|
506 default:
|
|
507 llvm_unreachable("unexpected opcode!");
|
|
508 case AVR::JMPk:
|
|
509 case AVR::CALLk:
|
|
510 case AVR::RCALLk:
|
|
511 case AVR::RJMPk:
|
|
512 case AVR::BREQk:
|
|
513 case AVR::BRNEk:
|
|
514 case AVR::BRSHk:
|
|
515 case AVR::BRLOk:
|
|
516 case AVR::BRMIk:
|
|
517 case AVR::BRPLk:
|
|
518 case AVR::BRGEk:
|
|
519 case AVR::BRLTk:
|
|
520 return MI.getOperand(0).getMBB();
|
|
521 case AVR::BRBSsk:
|
|
522 case AVR::BRBCsk:
|
|
523 return MI.getOperand(1).getMBB();
|
|
524 case AVR::SBRCRrB:
|
|
525 case AVR::SBRSRrB:
|
|
526 case AVR::SBICAb:
|
|
527 case AVR::SBISAb:
|
|
528 llvm_unreachable("unimplemented branch instructions");
|
|
529 }
|
|
530 }
|
|
531
|
|
532 bool AVRInstrInfo::isBranchOffsetInRange(unsigned BranchOp,
|
|
533 int64_t BrOffset) const {
|
|
534
|
|
535 switch (BranchOp) {
|
|
536 default:
|
|
537 llvm_unreachable("unexpected opcode!");
|
|
538 case AVR::JMPk:
|
|
539 case AVR::CALLk:
|
|
540 return true;
|
|
541 case AVR::RCALLk:
|
|
542 case AVR::RJMPk:
|
|
543 return isIntN(13, BrOffset);
|
|
544 case AVR::BRBSsk:
|
|
545 case AVR::BRBCsk:
|
|
546 case AVR::BREQk:
|
|
547 case AVR::BRNEk:
|
|
548 case AVR::BRSHk:
|
|
549 case AVR::BRLOk:
|
|
550 case AVR::BRMIk:
|
|
551 case AVR::BRPLk:
|
|
552 case AVR::BRGEk:
|
|
553 case AVR::BRLTk:
|
|
554 return isIntN(7, BrOffset);
|
|
555 }
|
|
556 }
|
|
557
|
|
558 unsigned AVRInstrInfo::insertIndirectBranch(MachineBasicBlock &MBB,
|
|
559 MachineBasicBlock &NewDestBB,
|
|
560 const DebugLoc &DL,
|
|
561 int64_t BrOffset,
|
|
562 RegScavenger *RS) const {
|
|
563 // This method inserts a *direct* branch (JMP), despite its name.
|
|
564 // LLVM calls this method to fixup unconditional branches; it never calls
|
|
565 // insertBranch or some hypothetical "insertDirectBranch".
|
|
566 // See lib/CodeGen/RegisterRelaxation.cpp for details.
|
|
567 // We end up here when a jump is too long for a RJMP instruction.
|
|
568 auto &MI = *BuildMI(&MBB, DL, get(AVR::JMPk)).addMBB(&NewDestBB);
|
|
569
|
|
570 return getInstSizeInBytes(MI);
|
|
571 }
|
|
572
|
120
|
573 } // end of namespace llvm
|
|
574
|