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