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