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