• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 //===-- AVRInstrInfo.cpp - AVR Instruction Information --------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the AVR implementation of the TargetInstrInfo class.
11 //
12 //===----------------------------------------------------------------------===//
13 
14 #include "AVRInstrInfo.h"
15 
16 #include "llvm/ADT/STLExtras.h"
17 #include "llvm/CodeGen/MachineConstantPool.h"
18 #include "llvm/CodeGen/MachineFrameInfo.h"
19 #include "llvm/CodeGen/MachineInstrBuilder.h"
20 #include "llvm/CodeGen/MachineMemOperand.h"
21 #include "llvm/IR/Constants.h"
22 #include "llvm/IR/Function.h"
23 #include "llvm/MC/MCContext.h"
24 #include "llvm/Support/Debug.h"
25 #include "llvm/Support/ErrorHandling.h"
26 #include "llvm/Support/TargetRegistry.h"
27 
28 #include "AVR.h"
29 #include "AVRMachineFunctionInfo.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 
AVRInstrInfo()38 AVRInstrInfo::AVRInstrInfo()
39     : AVRGenInstrInfo(AVR::ADJCALLSTACKDOWN, AVR::ADJCALLSTACKUP), RI() {}
40 
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,const DebugLoc & DL,unsigned DestReg,unsigned SrcReg,bool KillSrc) const41 void AVRInstrInfo::copyPhysReg(MachineBasicBlock &MBB,
42                                MachineBasicBlock::iterator MI,
43                                const DebugLoc &DL, unsigned DestReg,
44                                unsigned SrcReg, bool KillSrc) const {
45   unsigned Opc;
46 
47   if (AVR::GPR8RegClass.contains(DestReg, SrcReg)) {
48     Opc = AVR::MOVRdRr;
49   } else if (AVR::DREGSRegClass.contains(DestReg, SrcReg)) {
50     Opc = AVR::MOVWRdRr;
51   } else if (SrcReg == AVR::SP && AVR::DREGSRegClass.contains(DestReg)) {
52     Opc = AVR::SPREAD;
53   } else if (DestReg == AVR::SP && AVR::DREGSRegClass.contains(SrcReg)) {
54     Opc = AVR::SPWRITE;
55   } else {
56     llvm_unreachable("Impossible reg-to-reg copy");
57   }
58 
59   BuildMI(MBB, MI, DL, get(Opc), DestReg)
60       .addReg(SrcReg, getKillRegState(KillSrc));
61 }
62 
isLoadFromStackSlot(const MachineInstr & MI,int & FrameIndex) const63 unsigned AVRInstrInfo::isLoadFromStackSlot(const MachineInstr &MI,
64                                            int &FrameIndex) const {
65   switch (MI.getOpcode()) {
66   case AVR::LDDRdPtrQ:
67   case AVR::LDDWRdYQ: { //:FIXME: remove this once PR13375 gets fixed
68     if (MI.getOperand(1).isFI() && MI.getOperand(2).isImm() &&
69         MI.getOperand(2).getImm() == 0) {
70       FrameIndex = MI.getOperand(1).getIndex();
71       return MI.getOperand(0).getReg();
72     }
73     break;
74   }
75   default:
76     break;
77   }
78 
79   return 0;
80 }
81 
isStoreToStackSlot(const MachineInstr & MI,int & FrameIndex) const82 unsigned AVRInstrInfo::isStoreToStackSlot(const MachineInstr &MI,
83                                           int &FrameIndex) const {
84   switch (MI.getOpcode()) {
85   case AVR::STDPtrQRr:
86   case AVR::STDWPtrQRr: {
87     if (MI.getOperand(0).isFI() && MI.getOperand(1).isImm() &&
88         MI.getOperand(1).getImm() == 0) {
89       FrameIndex = MI.getOperand(0).getIndex();
90       return MI.getOperand(2).getReg();
91     }
92     break;
93   }
94   default:
95     break;
96   }
97 
98   return 0;
99 }
100 
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,unsigned SrcReg,bool isKill,int FrameIndex,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const101 void AVRInstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
102                                        MachineBasicBlock::iterator MI,
103                                        unsigned SrcReg, bool isKill,
104                                        int FrameIndex,
105                                        const TargetRegisterClass *RC,
106                                        const TargetRegisterInfo *TRI) const {
107   MachineFunction &MF = *MBB.getParent();
108 
109   DebugLoc DL;
110   if (MI != MBB.end()) {
111     DL = MI->getDebugLoc();
112   }
113 
114   const MachineFrameInfo &MFI = *MF.getFrameInfo();
115 
116   MachineMemOperand *MMO = MF.getMachineMemOperand(
117       MachinePointerInfo::getFixedStack(MF, FrameIndex),
118       MachineMemOperand::MOStore, MFI.getObjectSize(FrameIndex),
119       MFI.getObjectAlignment(FrameIndex));
120 
121   unsigned Opcode = 0;
122   if (RC->hasType(MVT::i8)) {
123     Opcode = AVR::STDPtrQRr;
124   } else if (RC->hasType(MVT::i16)) {
125     Opcode = AVR::STDWPtrQRr;
126   } else {
127     llvm_unreachable("Cannot store this register into a stack slot!");
128   }
129 
130   BuildMI(MBB, MI, DL, get(Opcode))
131       .addFrameIndex(FrameIndex)
132       .addImm(0)
133       .addReg(SrcReg, getKillRegState(isKill))
134       .addMemOperand(MMO);
135 }
136 
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,unsigned DestReg,int FrameIndex,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI) const137 void AVRInstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
138                                         MachineBasicBlock::iterator MI,
139                                         unsigned DestReg, int FrameIndex,
140                                         const TargetRegisterClass *RC,
141                                         const TargetRegisterInfo *TRI) const {
142   DebugLoc DL;
143   if (MI != MBB.end()) {
144     DL = MI->getDebugLoc();
145   }
146 
147   MachineFunction &MF = *MBB.getParent();
148   const MachineFrameInfo &MFI = *MF.getFrameInfo();
149 
150   MachineMemOperand *MMO = MF.getMachineMemOperand(
151       MachinePointerInfo::getFixedStack(MF, FrameIndex),
152       MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIndex),
153       MFI.getObjectAlignment(FrameIndex));
154 
155   unsigned Opcode = 0;
156   if (RC->hasType(MVT::i8)) {
157     Opcode = AVR::LDDRdPtrQ;
158   } else if (RC->hasType(MVT::i16)) {
159     // Opcode = AVR::LDDWRdPtrQ;
160     //:FIXME: remove this once PR13375 gets fixed
161     Opcode = AVR::LDDWRdYQ;
162   } else {
163     llvm_unreachable("Cannot load this register from a stack slot!");
164   }
165 
166   BuildMI(MBB, MI, DL, get(Opcode), DestReg)
167       .addFrameIndex(FrameIndex)
168       .addImm(0)
169       .addMemOperand(MMO);
170 }
171 
getBrCond(AVRCC::CondCodes CC) const172 const MCInstrDesc &AVRInstrInfo::getBrCond(AVRCC::CondCodes CC) const {
173   switch (CC) {
174   default:
175     llvm_unreachable("Unknown condition code!");
176   case AVRCC::COND_EQ:
177     return get(AVR::BREQk);
178   case AVRCC::COND_NE:
179     return get(AVR::BRNEk);
180   case AVRCC::COND_GE:
181     return get(AVR::BRGEk);
182   case AVRCC::COND_LT:
183     return get(AVR::BRLTk);
184   case AVRCC::COND_SH:
185     return get(AVR::BRSHk);
186   case AVRCC::COND_LO:
187     return get(AVR::BRLOk);
188   case AVRCC::COND_MI:
189     return get(AVR::BRMIk);
190   case AVRCC::COND_PL:
191     return get(AVR::BRPLk);
192   }
193 }
194 
getCondFromBranchOpc(unsigned Opc) const195 AVRCC::CondCodes AVRInstrInfo::getCondFromBranchOpc(unsigned Opc) const {
196   switch (Opc) {
197   default:
198     return AVRCC::COND_INVALID;
199   case AVR::BREQk:
200     return AVRCC::COND_EQ;
201   case AVR::BRNEk:
202     return AVRCC::COND_NE;
203   case AVR::BRSHk:
204     return AVRCC::COND_SH;
205   case AVR::BRLOk:
206     return AVRCC::COND_LO;
207   case AVR::BRMIk:
208     return AVRCC::COND_MI;
209   case AVR::BRPLk:
210     return AVRCC::COND_PL;
211   case AVR::BRGEk:
212     return AVRCC::COND_GE;
213   case AVR::BRLTk:
214     return AVRCC::COND_LT;
215   }
216 }
217 
getOppositeCondition(AVRCC::CondCodes CC) const218 AVRCC::CondCodes AVRInstrInfo::getOppositeCondition(AVRCC::CondCodes CC) const {
219   switch (CC) {
220   default:
221     llvm_unreachable("Invalid condition!");
222   case AVRCC::COND_EQ:
223     return AVRCC::COND_NE;
224   case AVRCC::COND_NE:
225     return AVRCC::COND_EQ;
226   case AVRCC::COND_SH:
227     return AVRCC::COND_LO;
228   case AVRCC::COND_LO:
229     return AVRCC::COND_SH;
230   case AVRCC::COND_GE:
231     return AVRCC::COND_LT;
232   case AVRCC::COND_LT:
233     return AVRCC::COND_GE;
234   case AVRCC::COND_MI:
235     return AVRCC::COND_PL;
236   case AVRCC::COND_PL:
237     return AVRCC::COND_MI;
238   }
239 }
240 
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const241 bool AVRInstrInfo::analyzeBranch(MachineBasicBlock &MBB,
242                                  MachineBasicBlock *&TBB,
243                                  MachineBasicBlock *&FBB,
244                                  SmallVectorImpl<MachineOperand> &Cond,
245                                  bool AllowModify) const {
246   // Start from the bottom of the block and work up, examining the
247   // terminator instructions.
248   MachineBasicBlock::iterator I = MBB.end();
249   MachineBasicBlock::iterator UnCondBrIter = MBB.end();
250 
251   while (I != MBB.begin()) {
252     --I;
253     if (I->isDebugValue()) {
254       continue;
255     }
256 
257     // Working from the bottom, when we see a non-terminator
258     // instruction, we're done.
259     if (!isUnpredicatedTerminator(*I)) {
260       break;
261     }
262 
263     // A terminator that isn't a branch can't easily be handled
264     // by this analysis.
265     if (!I->getDesc().isBranch()) {
266       return true;
267     }
268 
269     // Handle unconditional branches.
270     //:TODO: add here jmp
271     if (I->getOpcode() == AVR::RJMPk) {
272       UnCondBrIter = I;
273 
274       if (!AllowModify) {
275         TBB = I->getOperand(0).getMBB();
276         continue;
277       }
278 
279       // If the block has any instructions after a JMP, delete them.
280       while (std::next(I) != MBB.end()) {
281         std::next(I)->eraseFromParent();
282       }
283 
284       Cond.clear();
285       FBB = 0;
286 
287       // Delete the JMP if it's equivalent to a fall-through.
288       if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
289         TBB = 0;
290         I->eraseFromParent();
291         I = MBB.end();
292         UnCondBrIter = MBB.end();
293         continue;
294       }
295 
296       // TBB is used to indicate the unconditinal destination.
297       TBB = I->getOperand(0).getMBB();
298       continue;
299     }
300 
301     // Handle conditional branches.
302     AVRCC::CondCodes BranchCode = getCondFromBranchOpc(I->getOpcode());
303     if (BranchCode == AVRCC::COND_INVALID) {
304       return true; // Can't handle indirect branch.
305     }
306 
307     // Working from the bottom, handle the first conditional branch.
308     if (Cond.empty()) {
309       MachineBasicBlock *TargetBB = I->getOperand(0).getMBB();
310       if (AllowModify && UnCondBrIter != MBB.end() &&
311           MBB.isLayoutSuccessor(TargetBB)) {
312         // If we can modify the code and it ends in something like:
313         //
314         //     jCC L1
315         //     jmp L2
316         //   L1:
317         //     ...
318         //   L2:
319         //
320         // Then we can change this to:
321         //
322         //     jnCC L2
323         //   L1:
324         //     ...
325         //   L2:
326         //
327         // Which is a bit more efficient.
328         // We conditionally jump to the fall-through block.
329         BranchCode = getOppositeCondition(BranchCode);
330         unsigned JNCC = getBrCond(BranchCode).getOpcode();
331         MachineBasicBlock::iterator OldInst = I;
332 
333         BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(JNCC))
334             .addMBB(UnCondBrIter->getOperand(0).getMBB());
335         BuildMI(MBB, UnCondBrIter, MBB.findDebugLoc(I), get(AVR::RJMPk))
336             .addMBB(TargetBB);
337 
338         OldInst->eraseFromParent();
339         UnCondBrIter->eraseFromParent();
340 
341         // Restart the analysis.
342         UnCondBrIter = MBB.end();
343         I = MBB.end();
344         continue;
345       }
346 
347       FBB = TBB;
348       TBB = I->getOperand(0).getMBB();
349       Cond.push_back(MachineOperand::CreateImm(BranchCode));
350       continue;
351     }
352 
353     // Handle subsequent conditional branches. Only handle the case where all
354     // conditional branches branch to the same destination.
355     assert(Cond.size() == 1);
356     assert(TBB);
357 
358     // Only handle the case where all conditional branches branch to
359     // the same destination.
360     if (TBB != I->getOperand(0).getMBB()) {
361       return true;
362     }
363 
364     AVRCC::CondCodes OldBranchCode = (AVRCC::CondCodes)Cond[0].getImm();
365     // If the conditions are the same, we can leave them alone.
366     if (OldBranchCode == BranchCode) {
367       continue;
368     }
369 
370     return true;
371   }
372 
373   return false;
374 }
375 
InsertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL) const376 unsigned AVRInstrInfo::InsertBranch(MachineBasicBlock &MBB,
377                                     MachineBasicBlock *TBB,
378                                     MachineBasicBlock *FBB,
379                                     ArrayRef<MachineOperand> Cond,
380                                     const DebugLoc &DL) const {
381   // Shouldn't be a fall through.
382   assert(TBB && "InsertBranch must not be told to insert a fallthrough");
383   assert((Cond.size() == 1 || Cond.size() == 0) &&
384          "AVR branch conditions have one component!");
385 
386   if (Cond.empty()) {
387     assert(!FBB && "Unconditional branch with multiple successors!");
388     BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(TBB);
389     return 1;
390   }
391 
392   // Conditional branch.
393   unsigned Count = 0;
394   AVRCC::CondCodes CC = (AVRCC::CondCodes)Cond[0].getImm();
395   BuildMI(&MBB, DL, getBrCond(CC)).addMBB(TBB);
396   ++Count;
397 
398   if (FBB) {
399     // Two-way Conditional branch. Insert the second branch.
400     BuildMI(&MBB, DL, get(AVR::RJMPk)).addMBB(FBB);
401     ++Count;
402   }
403 
404   return Count;
405 }
406 
RemoveBranch(MachineBasicBlock & MBB) const407 unsigned AVRInstrInfo::RemoveBranch(MachineBasicBlock &MBB) const {
408   MachineBasicBlock::iterator I = MBB.end();
409   unsigned Count = 0;
410 
411   while (I != MBB.begin()) {
412     --I;
413     if (I->isDebugValue()) {
414       continue;
415     }
416     //:TODO: add here the missing jmp instructions once they are implemented
417     // like jmp, {e}ijmp, and other cond branches, ...
418     if (I->getOpcode() != AVR::RJMPk &&
419         getCondFromBranchOpc(I->getOpcode()) == AVRCC::COND_INVALID) {
420       break;
421     }
422 
423     // Remove the branch.
424     I->eraseFromParent();
425     I = MBB.end();
426     ++Count;
427   }
428 
429   return Count;
430 }
431 
ReverseBranchCondition(SmallVectorImpl<MachineOperand> & Cond) const432 bool AVRInstrInfo::ReverseBranchCondition(
433     SmallVectorImpl<MachineOperand> &Cond) const {
434   assert(Cond.size() == 1 && "Invalid AVR branch condition!");
435 
436   AVRCC::CondCodes CC = static_cast<AVRCC::CondCodes>(Cond[0].getImm());
437   Cond[0].setImm(getOppositeCondition(CC));
438 
439   return false;
440 }
441 
GetInstSizeInBytes(const MachineInstr * MI) const442 unsigned AVRInstrInfo::GetInstSizeInBytes(const MachineInstr *MI) const {
443   unsigned Opcode = MI->getOpcode();
444 
445   switch (Opcode) {
446   // A regular instruction
447   default: {
448     const MCInstrDesc &Desc = get(Opcode);
449     return Desc.getSize();
450   }
451   case TargetOpcode::EH_LABEL:
452   case TargetOpcode::IMPLICIT_DEF:
453   case TargetOpcode::KILL:
454   case TargetOpcode::DBG_VALUE:
455     return 0;
456   case TargetOpcode::INLINEASM: {
457     const MachineFunction *MF = MI->getParent()->getParent();
458     const AVRTargetMachine &TM = static_cast<const AVRTargetMachine&>(MF->getTarget());
459     const TargetInstrInfo &TII = *TM.getSubtargetImpl()->getInstrInfo();
460     return TII.getInlineAsmLength(MI->getOperand(0).getSymbolName(),
461                                   *TM.getMCAsmInfo());
462   }
463   }
464 }
465 
466 } // end of namespace llvm
467