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.
anchor()30 void MSP430InstrInfo::anchor() {}
31
MSP430InstrInfo(MSP430Subtarget & STI)32 MSP430InstrInfo::MSP430InstrInfo(MSP430Subtarget &STI)
33 : MSP430GenInstrInfo(MSP430::ADJCALLSTACKDOWN, MSP430::ADJCALLSTACKUP),
34 RI() {}
35
storeRegToStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,Register SrcReg,bool isKill,int FrameIdx,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,Register VReg) const36 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
loadRegFromStackSlot(MachineBasicBlock & MBB,MachineBasicBlock::iterator MI,Register DestReg,int FrameIdx,const TargetRegisterClass * RC,const TargetRegisterInfo * TRI,Register VReg) const62 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
copyPhysReg(MachineBasicBlock & MBB,MachineBasicBlock::iterator I,const DebugLoc & DL,MCRegister DestReg,MCRegister SrcReg,bool KillSrc) const90 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
removeBranch(MachineBasicBlock & MBB,int * BytesRemoved) const106 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::
reverseBranchCondition(SmallVectorImpl<MachineOperand> & Cond) const133 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
analyzeBranch(MachineBasicBlock & MBB,MachineBasicBlock * & TBB,MachineBasicBlock * & FBB,SmallVectorImpl<MachineOperand> & Cond,bool AllowModify) const164 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
insertBranch(MachineBasicBlock & MBB,MachineBasicBlock * TBB,MachineBasicBlock * FBB,ArrayRef<MachineOperand> Cond,const DebugLoc & DL,int * BytesAdded) const253 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 ///
getInstSizeInBytes(const MachineInstr & MI) const288 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