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
36namespace llvm {
37
38AVRInstrInfo::AVRInstrInfo()
39    : AVRGenInstrInfo(AVR::ADJCALLSTACKDOWN, AVR::ADJCALLSTACKUP), RI() {}
40
41void 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
63unsigned 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
82unsigned 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
101void 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
137void 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
172const 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
195AVRCC::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
218AVRCC::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
241bool 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
376unsigned 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
407unsigned 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
432bool 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
442unsigned 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