xref: /freebsd/contrib/llvm-project/llvm/lib/Target/MSP430/MSP430InstrInfo.cpp (revision 02e9120893770924227138ba49df1edb3896112a)
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/MC/TargetRegistry.h"
22 #include "llvm/Support/ErrorHandling.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(
37     MachineBasicBlock &MBB, MachineBasicBlock::iterator MI, Register SrcReg,
38     bool isKill, int FrameIdx, const TargetRegisterClass *RC,
39     const TargetRegisterInfo *TRI, Register VReg) const {
40   DebugLoc DL;
41   if (MI != MBB.end()) DL = MI->getDebugLoc();
42   MachineFunction &MF = *MBB.getParent();
43   MachineFrameInfo &MFI = MF.getFrameInfo();
44 
45   MachineMemOperand *MMO = MF.getMachineMemOperand(
46       MachinePointerInfo::getFixedStack(MF, FrameIdx),
47       MachineMemOperand::MOStore, MFI.getObjectSize(FrameIdx),
48       MFI.getObjectAlign(FrameIdx));
49 
50   if (RC == &MSP430::GR16RegClass)
51     BuildMI(MBB, MI, DL, get(MSP430::MOV16mr))
52       .addFrameIndex(FrameIdx).addImm(0)
53       .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
54   else if (RC == &MSP430::GR8RegClass)
55     BuildMI(MBB, MI, DL, get(MSP430::MOV8mr))
56       .addFrameIndex(FrameIdx).addImm(0)
57       .addReg(SrcReg, getKillRegState(isKill)).addMemOperand(MMO);
58   else
59     llvm_unreachable("Cannot store this register to stack slot!");
60 }
61 
62 void MSP430InstrInfo::loadRegFromStackSlot(MachineBasicBlock &MBB,
63                                            MachineBasicBlock::iterator MI,
64                                            Register DestReg, int FrameIdx,
65                                            const TargetRegisterClass *RC,
66                                            const TargetRegisterInfo *TRI,
67                                            Register VReg) 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.getObjectAlign(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::Bi &&
120         I->getOpcode() != MSP430::Br &&
121         I->getOpcode() != MSP430::Bm)
122       break;
123     // Remove the branch.
124     I->eraseFromParent();
125     I = MBB.end();
126     ++Count;
127   }
128 
129   return Count;
130 }
131 
132 bool MSP430InstrInfo::
133 reverseBranchCondition(SmallVectorImpl<MachineOperand> &Cond) const {
134   assert(Cond.size() == 1 && "Invalid Xbranch condition!");
135 
136   MSP430CC::CondCodes CC = static_cast<MSP430CC::CondCodes>(Cond[0].getImm());
137 
138   switch (CC) {
139   default: llvm_unreachable("Invalid branch condition!");
140   case MSP430CC::COND_E:
141     CC = MSP430CC::COND_NE;
142     break;
143   case MSP430CC::COND_NE:
144     CC = MSP430CC::COND_E;
145     break;
146   case MSP430CC::COND_L:
147     CC = MSP430CC::COND_GE;
148     break;
149   case MSP430CC::COND_GE:
150     CC = MSP430CC::COND_L;
151     break;
152   case MSP430CC::COND_HS:
153     CC = MSP430CC::COND_LO;
154     break;
155   case MSP430CC::COND_LO:
156     CC = MSP430CC::COND_HS;
157     break;
158   }
159 
160   Cond[0].setImm(CC);
161   return false;
162 }
163 
164 bool MSP430InstrInfo::analyzeBranch(MachineBasicBlock &MBB,
165                                     MachineBasicBlock *&TBB,
166                                     MachineBasicBlock *&FBB,
167                                     SmallVectorImpl<MachineOperand> &Cond,
168                                     bool AllowModify) const {
169   // Start from the bottom of the block and work up, examining the
170   // terminator instructions.
171   MachineBasicBlock::iterator I = MBB.end();
172   while (I != MBB.begin()) {
173     --I;
174     if (I->isDebugInstr())
175       continue;
176 
177     // Working from the bottom, when we see a non-terminator
178     // instruction, we're done.
179     if (!isUnpredicatedTerminator(*I))
180       break;
181 
182     // A terminator that isn't a branch can't easily be handled
183     // by this analysis.
184     if (!I->isBranch())
185       return true;
186 
187     // Cannot handle indirect branches.
188     if (I->getOpcode() == MSP430::Br ||
189         I->getOpcode() == MSP430::Bm)
190       return true;
191 
192     // Handle unconditional branches.
193     if (I->getOpcode() == MSP430::JMP || I->getOpcode() == MSP430::Bi) {
194       if (!AllowModify) {
195         TBB = I->getOperand(0).getMBB();
196         continue;
197       }
198 
199       // If the block has any instructions after a JMP, delete them.
200       MBB.erase(std::next(I), MBB.end());
201       Cond.clear();
202       FBB = nullptr;
203 
204       // Delete the JMP if it's equivalent to a fall-through.
205       if (MBB.isLayoutSuccessor(I->getOperand(0).getMBB())) {
206         TBB = nullptr;
207         I->eraseFromParent();
208         I = MBB.end();
209         continue;
210       }
211 
212       // TBB is used to indicate the unconditinal destination.
213       TBB = I->getOperand(0).getMBB();
214       continue;
215     }
216 
217     // Handle conditional branches.
218     assert(I->getOpcode() == MSP430::JCC && "Invalid conditional branch");
219     MSP430CC::CondCodes BranchCode =
220       static_cast<MSP430CC::CondCodes>(I->getOperand(1).getImm());
221     if (BranchCode == MSP430CC::COND_INVALID)
222       return true;  // Can't handle weird stuff.
223 
224     // Working from the bottom, handle the first conditional branch.
225     if (Cond.empty()) {
226       FBB = TBB;
227       TBB = I->getOperand(0).getMBB();
228       Cond.push_back(MachineOperand::CreateImm(BranchCode));
229       continue;
230     }
231 
232     // Handle subsequent conditional branches. Only handle the case where all
233     // conditional branches branch to the same destination.
234     assert(Cond.size() == 1);
235     assert(TBB);
236 
237     // Only handle the case where all conditional branches branch to
238     // the same destination.
239     if (TBB != I->getOperand(0).getMBB())
240       return true;
241 
242     MSP430CC::CondCodes OldBranchCode = (MSP430CC::CondCodes)Cond[0].getImm();
243     // If the conditions are the same, we can leave them alone.
244     if (OldBranchCode == BranchCode)
245       continue;
246 
247     return true;
248   }
249 
250   return false;
251 }
252 
253 unsigned MSP430InstrInfo::insertBranch(MachineBasicBlock &MBB,
254                                        MachineBasicBlock *TBB,
255                                        MachineBasicBlock *FBB,
256                                        ArrayRef<MachineOperand> Cond,
257                                        const DebugLoc &DL,
258                                        int *BytesAdded) const {
259   // Shouldn't be a fall through.
260   assert(TBB && "insertBranch must not be told to insert a fallthrough");
261   assert((Cond.size() == 1 || Cond.size() == 0) &&
262          "MSP430 branch conditions have one component!");
263   assert(!BytesAdded && "code size not handled");
264 
265   if (Cond.empty()) {
266     // Unconditional branch?
267     assert(!FBB && "Unconditional branch with multiple successors!");
268     BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(TBB);
269     return 1;
270   }
271 
272   // Conditional branch.
273   unsigned Count = 0;
274   BuildMI(&MBB, DL, get(MSP430::JCC)).addMBB(TBB).addImm(Cond[0].getImm());
275   ++Count;
276 
277   if (FBB) {
278     // Two-way Conditional branch. Insert the second branch.
279     BuildMI(&MBB, DL, get(MSP430::JMP)).addMBB(FBB);
280     ++Count;
281   }
282   return Count;
283 }
284 
285 /// GetInstSize - Return the number of bytes of code the specified
286 /// instruction may be.  This returns the maximum number of bytes.
287 ///
288 unsigned MSP430InstrInfo::getInstSizeInBytes(const MachineInstr &MI) const {
289   const MCInstrDesc &Desc = MI.getDesc();
290 
291   switch (Desc.getOpcode()) {
292   case TargetOpcode::CFI_INSTRUCTION:
293   case TargetOpcode::EH_LABEL:
294   case TargetOpcode::IMPLICIT_DEF:
295   case TargetOpcode::KILL:
296   case TargetOpcode::DBG_VALUE:
297     return 0;
298   case TargetOpcode::INLINEASM:
299   case TargetOpcode::INLINEASM_BR: {
300     const MachineFunction *MF = MI.getParent()->getParent();
301     const TargetInstrInfo &TII = *MF->getSubtarget().getInstrInfo();
302     return TII.getInlineAsmLength(MI.getOperand(0).getSymbolName(),
303                                   *MF->getTarget().getMCAsmInfo());
304   }
305   }
306 
307   return Desc.getSize();
308 }
309