1 //===-- MSP430InstrInfo.cpp - MSP430 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 MSP430 implementation of the TargetInstrInfo class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "MSP430InstrInfo.h"
14 #include "MSP430.h"
15 #include "MSP430MachineFunctionInfo.h"
16 #include "MSP430TargetMachine.h"
17 #include "llvm/CodeGen/MachineFrameInfo.h"
18 #include "llvm/CodeGen/MachineInstrBuilder.h"
19 #include "llvm/CodeGen/MachineRegisterInfo.h"
20 #include "llvm/IR/Function.h"
21 #include "llvm/Support/ErrorHandling.h"
22 #include "llvm/Support/TargetRegistry.h"
23 
24 using namespace llvm;
25 
26 #define GET_INSTRINFO_CTOR_DTOR
27 #include "MSP430GenInstrInfo.inc"
28 
29 // Pin the vtable to this file.
30 void MSP430InstrInfo::anchor() {}
31 
32 MSP430InstrInfo::MSP430InstrInfo(MSP430Subtarget &STI)
33   : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
34     RI() {}
35 
36 void MSP430InstrInfo::storeRegToStackSlot(MachineBasicBlock &MBB,
37                                           MachineBasicBlock::iterator MI,
38                                     unsigned SrcReg, bool isKill, int FrameIdx,
39                                           const TargetRegisterClass *RC,
40                                           const TargetRegisterInfo *TRI) const {
41   DebugLoc DL;
42   if (MI != MBB.end()) DL = MI->getDebugLoc();
43   MachineFunction &MF = *MBB.getParent();
44   MachineFrameInfo &MFI = MF.getFrameInfo();
45 
46   MachineMemOperand *MMO = MF.getMachineMemOperand(
47       MachinePointerInfo::getFixedStack(MF, FrameIdx),
48       MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
49       MFI.getObjectAlignment(FrameIdx));
50 
51   if (RC == &MSP430::GR16RegClass)
52     BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
53       .addFrameIndex(FrameIdx).addImm(0)
54       .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
55   else if (RC == &MSP430::GR8RegClass)
56     BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
57       .addFrameIndex(FrameIdx).addImm(0)
58       .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
59   else
60     llvm_unreachable("Cannot store this register to stack slot!");
61 }
62 
63 void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
64                                            MachineBasicBlock::iterator MI,
65                                            unsigned DestReg, int FrameIdx,
66                                            const TargetRegisterClass *RC,
67                                            const TargetRegisterInfo *TRI) const{
68   DebugLoc DL;
69   if (MI != MBB.end()) DL = MI->getDebugLoc();
70   MachineFunction &MF = *MBB.getParent();
71   MachineFrameInfo &MFI = MF.getFrameInfo();
72 
73   MachineMemOperand *MMO = MF.getMachineMemOperand(
74       MachinePointerInfo::getFixedStack(MF, FrameIdx),
75       MachineMemOperand::MOLoad, MFI.getObjectSize(FrameIdx),
76       MFI.getObjectAlignment(FrameIdx));
77 
78   if (RC == &MSP430::GR16RegClass)
79     BuildMI(MBB, MI, DL, get(MSP430::MOV16rm))
80       .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
81       .addImm(0).addMemOperand(MMO);
82   else if (RC == &MSP430::GR8RegClass)
83     BuildMI(MBB, MI, DL, get(MSP430::MOV8rm))
84       .addReg(DestReg, getDefRegState(true)).addFrameIndex(FrameIdx)
85       .addImm(0).addMemOperand(MMO);
86   else
87     llvm_unreachable("Cannot store this register to stack slot!");
88 }
89 
90 void MSP430InstrInfo::copyPhysReg(MachineBasicBlock &MBB,
91                                   MachineBasicBlock::iterator I,
92                                   const DebugLoc &DL, MCRegister DestReg,
93                                   MCRegister SrcReg, bool KillSrc) const {
94   unsigned Opc;
95   if (MSP430::GR16RegClass.contains(DestReg, SrcReg))
96     Opc = MSP430::MOV16rr;
97   else if (MSP430::GR8RegClass.contains(DestReg, SrcReg))
98     Opc = MSP430::MOV8rr;
99   else
100     llvm_unreachable("Impossible reg-to-reg copy");
101 
102   BuildMI(MBB, I, DL, get(Opc), DestReg)
103     .addReg(SrcReg, getKillRegState(KillSrc));
104 }
105 
106 unsigned MSP430InstrInfo::removeBranch(MachineBasicBlock &MBB,
107                                        int *BytesRemoved) const {
108   assert(!BytesRemoved && "code size not handled");
109 
110   MachineBasicBlock::iterator I = MBB.end();
111   unsigned Count = 0;
112 
113   while (I != MBB.begin()) {
114     --I;
115     if (I->isDebugInstr())
116       continue;
117     if (I->getOpcode() != MSP430::JMP &&
118         I->getOpcode() != MSP430::JCC &&
119         I->getOpcode() != MSP430::Br &&
120         I->getOpcode() != MSP430::Bm)
121       break;
122     // Remove the branch.
123     I->eraseFromParent();
124     I = MBB.end();
125     ++Count;
126   }
127 
128   return Count;
129 }
130 
131 bool MSP430InstrInfo::
132 reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
133   assert(Cond.size() == 1 && "Invalid Xbranch condition!");
134 
135   MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
136 
137   switch (CC) {
138   default: llvm_unreachable("Invalid branch condition!");
139   case MSP430CC::COND_E:
140     CC = MSP430CC::COND_NE;
141     break;
142   case MSP430CC::COND_NE:
143     CC = MSP430CC::COND_E;
144     break;
145   case MSP430CC::COND_L:
146     CC = MSP430CC::COND_GE;
147     break;
148   case MSP430CC::COND_GE:
149     CC = MSP430CC::COND_L;
150     break;
151   case MSP430CC::COND_HS:
152     CC = MSP430CC::COND_LO;
153     break;
154   case MSP430CC::COND_LO:
155     CC = MSP430CC::COND_HS;
156     break;
157   }
158 
159   Cond[0].setImm(CC);
160   return false;
161 }
162 
163 bool MSP430InstrInfo::isUnpredicatedTerminator(const MachineInstr &MI) const {
164   if (!MI.isTerminator())
165     return false;
166 
167   // Conditional branch is a special case.
168   if (MI.isBranch() && !MI.isBarrier())
169     return true;
170   if (!MI.isPredicable())
171     return true;
172   return !isPredicated(MI);
173 }
174 
175 bool MSP430InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
176                                     MachineBasicBlock *&TBB,
177                                     MachineBasicBlock *&FBB,
178                                     SmallVectorImpl<MachineOperand> &Cond,
179                                     bool AllowModify) const {
180   // Start from the bottom of the block and work up, examining the
181   // terminator instructions.
182   MachineBasicBlock::iterator I = MBB.end();
183   while (I != MBB.begin()) {
184     --I;
185     if (I->isDebugInstr())
186       continue;
187 
188     // Working from the bottom, when we see a non-terminator
189     // instruction, we're done.
190     if (!isUnpredicatedTerminator(*I))
191       break;
192 
193     // A terminator that isn't a branch can't easily be handled
194     // by this analysis.
195     if (!I->isBranch())
196       return true;
197 
198     // Cannot handle indirect branches.
199     if (I->getOpcode() == MSP430::Br ||
200         I->getOpcode() == MSP430::Bm)
201       return true;
202 
203     // Handle unconditional branches.
204     if (I->getOpcode() == MSP430::JMP) {
205       if (!AllowModify) {
206         TBB = I->getOperand(0).getMBB();
207         continue;
208       }
209 
210       // If the block has any instructions after a JMP, delete them.
211       while (std::next(I) != MBB.end())
212         std::next(I)->eraseFromParent();
213       Cond.clear();
214       FBB = nullptr;
215 
216       // Delete the JMP if it's equivalent to a fall-through.
217       if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
218         TBB = nullptr;
219         I->eraseFromParent();
220         I = MBB.end();
221         continue;
222       }
223 
224       // TBB is used to indicate the unconditinal destination.
225       TBB = I->getOperand(0).getMBB();
226       continue;
227     }
228 
229     // Handle conditional branches.
230     assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
231     MSP430CC::CondCodes BranchCode =
232       static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
233     if (BranchCode == MSP430CC::COND_INVALID)
234       return true;  // Can't handle weird stuff.
235 
236     // Working from the bottom, handle the first conditional branch.
237     if (Cond.empty()) {
238       FBB = TBB;
239       TBB = I->getOperand(0).getMBB();
240       Cond.push_back(MachineOperand::CreateImm(BranchCode));
241       continue;
242     }
243 
244     // Handle subsequent conditional branches. Only handle the case where all
245     // conditional branches branch to the same destination.
246     assert(Cond.size() == 1);
247     assert(TBB);
248 
249     // Only handle the case where all conditional branches branch to
250     // the same destination.
251     if (TBB != I->getOperand(0).getMBB())
252       return true;
253 
254     MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
255     // If the conditions are the same, we can leave them alone.
256     if (OldBranchCode == BranchCode)
257       continue;
258 
259     return true;
260   }
261 
262   return false;
263 }
264 
265 unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB,
266                                        MachineBasicBlock *TBB,
267                                        MachineBasicBlock *FBB,
268                                        ArrayRef<MachineOperand> Cond,
269                                        const DebugLoc &DL,
270                                        int *BytesAdded) const {
271   // Shouldn't be a fall through.
272   assert(TBB && "insertBranch must not be told to insert a fallthrough");
273   assert((Cond.size() == 1 || Cond.size() == 0) &&
274          "MSP430 branch conditions have one component!");
275   assert(!BytesAdded && "code size not handled");
276 
277   if (Cond.empty()) {
278     // Unconditional branch?
279     assert(!FBB && "Unconditional branch with multiple successors!");
280     BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
281     return 1;
282   }
283 
284   // Conditional branch.
285   unsigned Count = 0;
286   BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
287   ++Count;
288 
289   if (FBB) {
290     // Two-way Conditional branch. Insert the second branch.
291     BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
292     ++Count;
293   }
294   return Count;
295 }
296 
297 /// GetInstSize - Return the number of bytes of code the specified
298 /// instruction may be.  This returns the maximum number of bytes.
299 ///
300 unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
301   const MCInstrDesc &Desc = MI.getDesc();
302 
303   switch (Desc.getOpcode()) {
304   case TargetOpcode::CFI_INSTRUCTION:
305   case TargetOpcode::EH_LABEL:
306   case TargetOpcode::IMPLICIT_DEF:
307   case TargetOpcode::KILL:
308   case TargetOpcode::DBG_VALUE:
309     return 0;
310   case TargetOpcode::INLINEASM:
311   case TargetOpcode::INLINEASM_BR: {
312     const MachineFunction *MF = MI.getParent()->getParent();
313     const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
314     return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
315                                   *MF->getTarget().getMCAsmInfo());
316   }
317   }
318 
319   return Desc.getSize();
320 }
321