/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/lib/Target/Mips/Mips16InstrInfo.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- Mips16InstrInfo.cpp - Mips16 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 Mips16 implementation of the TargetInstrInfo class. |
11 | | // |
12 | | //===----------------------------------------------------------------------===// |
13 | | |
14 | | #include "Mips16InstrInfo.h" |
15 | | #include "llvm/ADT/BitVector.h" |
16 | | #include "llvm/CodeGen/MachineBasicBlock.h" |
17 | | #include "llvm/CodeGen/MachineFrameInfo.h" |
18 | | #include "llvm/CodeGen/MachineFunction.h" |
19 | | #include "llvm/CodeGen/MachineInstr.h" |
20 | | #include "llvm/CodeGen/MachineInstrBuilder.h" |
21 | | #include "llvm/CodeGen/MachineMemOperand.h" |
22 | | #include "llvm/CodeGen/MachineOperand.h" |
23 | | #include "llvm/CodeGen/RegisterScavenging.h" |
24 | | #include "llvm/IR/DebugLoc.h" |
25 | | #include "llvm/MC/MCAsmInfo.h" |
26 | | #include "llvm/Support/Debug.h" |
27 | | #include "llvm/Support/ErrorHandling.h" |
28 | | #include "llvm/Support/MathExtras.h" |
29 | | #include "llvm/Support/raw_ostream.h" |
30 | | #include "llvm/Target/TargetRegisterInfo.h" |
31 | | #include <cassert> |
32 | | #include <cctype> |
33 | | #include <cstdint> |
34 | | #include <cstdlib> |
35 | | #include <cstring> |
36 | | #include <iterator> |
37 | | #include <vector> |
38 | | |
39 | | using namespace llvm; |
40 | | |
41 | | #define DEBUG_TYPE "mips16-instrinfo" |
42 | | |
43 | | Mips16InstrInfo::Mips16InstrInfo(const MipsSubtarget &STI) |
44 | 2.37k | : MipsInstrInfo(STI, Mips::Bimm16) {} |
45 | | |
46 | 92.1k | const MipsRegisterInfo &Mips16InstrInfo::getRegisterInfo() const { |
47 | 92.1k | return RI; |
48 | 92.1k | } |
49 | | |
50 | | /// isLoadFromStackSlot - If the specified machine instruction is a direct |
51 | | /// load from a stack slot, return the virtual or physical register number of |
52 | | /// the destination along with the FrameIndex of the loaded stack slot. If |
53 | | /// not, return 0. This predicate must return 0 if the instruction has |
54 | | /// any side effects other than loading from the stack slot. |
55 | | unsigned Mips16InstrInfo::isLoadFromStackSlot(const MachineInstr &MI, |
56 | 5.60k | int &FrameIndex) const { |
57 | 5.60k | return 0; |
58 | 5.60k | } |
59 | | |
60 | | /// isStoreToStackSlot - If the specified machine instruction is a direct |
61 | | /// store to a stack slot, return the virtual or physical register number of |
62 | | /// the source reg along with the FrameIndex of the loaded stack slot. If |
63 | | /// not, return 0. This predicate must return 0 if the instruction has |
64 | | /// any side effects other than storing to the stack slot. |
65 | | unsigned Mips16InstrInfo::isStoreToStackSlot(const MachineInstr &MI, |
66 | 2.80k | int &FrameIndex) const { |
67 | 2.80k | return 0; |
68 | 2.80k | } |
69 | | |
70 | | void Mips16InstrInfo::copyPhysReg(MachineBasicBlock &MBB, |
71 | | MachineBasicBlock::iterator I, |
72 | | const DebugLoc &DL, unsigned DestReg, |
73 | 1.53k | unsigned SrcReg, bool KillSrc) const { |
74 | 1.53k | unsigned Opc = 0; |
75 | 1.53k | |
76 | 1.53k | if (Mips::CPU16RegsRegClass.contains(DestReg) && |
77 | 434 | Mips::GPR32RegClass.contains(SrcReg)) |
78 | 426 | Opc = Mips::MoveR3216; |
79 | 1.10k | else if (1.10k Mips::GPR32RegClass.contains(DestReg) && |
80 | 1.10k | Mips::CPU16RegsRegClass.contains(SrcReg)) |
81 | 1.09k | Opc = Mips::Move32R16; |
82 | 8 | else if (8 (SrcReg == Mips::HI0) && |
83 | 4 | (Mips::CPU16RegsRegClass.contains(DestReg))) |
84 | 4 | Opc = Mips::Mfhi16, SrcReg = 0; |
85 | 4 | else if (4 (SrcReg == Mips::LO0) && |
86 | 4 | (Mips::CPU16RegsRegClass.contains(DestReg))) |
87 | 4 | Opc = Mips::Mflo16, SrcReg = 0; |
88 | 1.53k | |
89 | 1.53k | assert(Opc && "Cannot copy registers"); |
90 | 1.53k | |
91 | 1.53k | MachineInstrBuilder MIB = BuildMI(MBB, I, DL, get(Opc)); |
92 | 1.53k | |
93 | 1.53k | if (DestReg) |
94 | 1.53k | MIB.addReg(DestReg, RegState::Define); |
95 | 1.53k | |
96 | 1.53k | if (SrcReg) |
97 | 1.52k | MIB.addReg(SrcReg, getKillRegState(KillSrc)); |
98 | 1.53k | } |
99 | | |
100 | | void Mips16InstrInfo::storeRegToStack(MachineBasicBlock &MBB, |
101 | | MachineBasicBlock::iterator I, |
102 | | unsigned SrcReg, bool isKill, int FI, |
103 | | const TargetRegisterClass *RC, |
104 | | const TargetRegisterInfo *TRI, |
105 | 474 | int64_t Offset) const { |
106 | 474 | DebugLoc DL; |
107 | 474 | if (I != MBB.end()474 ) DL = I->getDebugLoc()472 ; |
108 | 474 | MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOStore); |
109 | 474 | unsigned Opc = 0; |
110 | 474 | if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) |
111 | 474 | Opc = Mips::SwRxSpImmX16; |
112 | 474 | assert(Opc && "Register class not handled!"); |
113 | 474 | BuildMI(MBB, I, DL, get(Opc)).addReg(SrcReg, getKillRegState(isKill)). |
114 | 474 | addFrameIndex(FI).addImm(Offset) |
115 | 474 | .addMemOperand(MMO); |
116 | 474 | } |
117 | | |
118 | | void Mips16InstrInfo::loadRegFromStack(MachineBasicBlock &MBB, |
119 | | MachineBasicBlock::iterator I, |
120 | | unsigned DestReg, int FI, |
121 | | const TargetRegisterClass *RC, |
122 | | const TargetRegisterInfo *TRI, |
123 | 641 | int64_t Offset) const { |
124 | 641 | DebugLoc DL; |
125 | 641 | if (I != MBB.end()641 ) DL = I->getDebugLoc()641 ; |
126 | 641 | MachineMemOperand *MMO = GetMemOperand(MBB, FI, MachineMemOperand::MOLoad); |
127 | 641 | unsigned Opc = 0; |
128 | 641 | |
129 | 641 | if (Mips::CPU16RegsRegClass.hasSubClassEq(RC)) |
130 | 641 | Opc = Mips::LwRxSpImmX16; |
131 | 641 | assert(Opc && "Register class not handled!"); |
132 | 641 | BuildMI(MBB, I, DL, get(Opc), DestReg).addFrameIndex(FI).addImm(Offset) |
133 | 641 | .addMemOperand(MMO); |
134 | 641 | } |
135 | | |
136 | 2.86k | bool Mips16InstrInfo::expandPostRAPseudo(MachineInstr &MI) const { |
137 | 2.86k | MachineBasicBlock &MBB = *MI.getParent(); |
138 | 2.86k | switch (MI.getDesc().getOpcode()) { |
139 | 2.48k | default: |
140 | 2.48k | return false; |
141 | 380 | case Mips::RetRA16: |
142 | 380 | ExpandRetRA16(MBB, MI, Mips::JrcRa16); |
143 | 380 | break; |
144 | 380 | } |
145 | 380 | |
146 | 380 | MBB.erase(MI.getIterator()); |
147 | 380 | return true; |
148 | 380 | } |
149 | | |
150 | | /// GetOppositeBranchOpc - Return the inverse of the specified |
151 | | /// opcode, e.g. turning BEQ to BNE. |
152 | 49 | unsigned Mips16InstrInfo::getOppositeBranchOpc(unsigned Opc) const { |
153 | 49 | switch (Opc) { |
154 | 0 | case Mips::BeqzRxImmX16: return Mips::BnezRxImmX16; |
155 | 0 | case Mips::BnezRxImmX16: return Mips::BeqzRxImmX16; |
156 | 5 | case Mips::BeqzRxImm16: return Mips::BnezRxImm16; |
157 | 11 | case Mips::BnezRxImm16: return Mips::BeqzRxImm16; |
158 | 0 | case Mips::BteqzT8CmpX16: return Mips::BtnezT8CmpX16; |
159 | 0 | case Mips::BteqzT8SltX16: return Mips::BtnezT8SltX16; |
160 | 0 | case Mips::BteqzT8SltiX16: return Mips::BtnezT8SltiX16; |
161 | 15 | case Mips::Btnez16: return Mips::Bteqz16; |
162 | 0 | case Mips::BtnezX16: return Mips::BteqzX16; |
163 | 0 | case Mips::BtnezT8CmpiX16: return Mips::BteqzT8CmpiX16; |
164 | 0 | case Mips::BtnezT8SltuX16: return Mips::BteqzT8SltuX16; |
165 | 0 | case Mips::BtnezT8SltiuX16: return Mips::BteqzT8SltiuX16; |
166 | 18 | case Mips::Bteqz16: return Mips::Btnez16; |
167 | 0 | case Mips::BteqzX16: return Mips::BtnezX16; |
168 | 0 | case Mips::BteqzT8CmpiX16: return Mips::BtnezT8CmpiX16; |
169 | 0 | case Mips::BteqzT8SltuX16: return Mips::BtnezT8SltuX16; |
170 | 0 | case Mips::BteqzT8SltiuX16: return Mips::BtnezT8SltiuX16; |
171 | 0 | case Mips::BtnezT8CmpX16: return Mips::BteqzT8CmpX16; |
172 | 0 | case Mips::BtnezT8SltX16: return Mips::BteqzT8SltX16; |
173 | 0 | case Mips::BtnezT8SltiX16: return Mips::BteqzT8SltiX16; |
174 | 0 | } |
175 | 0 | llvm_unreachable0 ("Illegal opcode!"); |
176 | 0 | } |
177 | | |
178 | | static void addSaveRestoreRegs(MachineInstrBuilder &MIB, |
179 | | const std::vector<CalleeSavedInfo> &CSI, |
180 | 490 | unsigned Flags = 0) { |
181 | 1.52k | for (unsigned i = 0, e = CSI.size(); i != e1.52k ; ++i1.03k ) { |
182 | 1.03k | // Add the callee-saved register as live-in. Do not add if the register is |
183 | 1.03k | // RA and return address is taken, because it has already been added in |
184 | 1.03k | // method MipsTargetLowering::lowerRETURNADDR. |
185 | 1.03k | // It's killed at the spill, unless the register is RA and return address |
186 | 1.03k | // is taken. |
187 | 1.03k | unsigned Reg = CSI[e-i-1].getReg(); |
188 | 1.03k | switch (Reg) { |
189 | 896 | case Mips::RA: |
190 | 896 | case Mips::S0: |
191 | 896 | case Mips::S1: |
192 | 896 | MIB.addReg(Reg, Flags); |
193 | 896 | break; |
194 | 138 | case Mips::S2: |
195 | 138 | break; |
196 | 0 | default: |
197 | 0 | llvm_unreachable("unexpected mips16 callee saved register"); |
198 | 1.03k | |
199 | 1.03k | } |
200 | 1.03k | } |
201 | 490 | } |
202 | | |
203 | | // Adjust SP by FrameSize bytes. Save RA, S0, S1 |
204 | | void Mips16InstrInfo::makeFrame(unsigned SP, int64_t FrameSize, |
205 | | MachineBasicBlock &MBB, |
206 | 246 | MachineBasicBlock::iterator I) const { |
207 | 246 | DebugLoc DL; |
208 | 246 | MachineFunction &MF = *MBB.getParent(); |
209 | 246 | MachineFrameInfo &MFI = MF.getFrameInfo(); |
210 | 246 | const BitVector Reserved = RI.getReservedRegs(MF); |
211 | 246 | bool SaveS2 = Reserved[Mips::S2]; |
212 | 246 | MachineInstrBuilder MIB; |
213 | 246 | unsigned Opc = ((FrameSize <= 128) && !SaveS2242 )? Mips::Save16174 :Mips::SaveX1672 ; |
214 | 246 | MIB = BuildMI(MBB, I, DL, get(Opc)); |
215 | 246 | const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); |
216 | 246 | addSaveRestoreRegs(MIB, CSI); |
217 | 246 | if (SaveS2) |
218 | 69 | MIB.addReg(Mips::S2); |
219 | 246 | if (isUInt<11>(FrameSize)) |
220 | 245 | MIB.addImm(FrameSize); |
221 | 1 | else { |
222 | 1 | int Base = 2040; // should create template function like isUInt that |
223 | 1 | // returns largest possible n bit unsigned integer |
224 | 1 | int64_t Remainder = FrameSize - Base; |
225 | 1 | MIB.addImm(Base); |
226 | 1 | if (isInt<16>(-Remainder)) |
227 | 1 | BuildAddiuSpImm(MBB, I, -Remainder); |
228 | 1 | else |
229 | 0 | adjustStackPtrBig(SP, -Remainder, MBB, I, Mips::V0, Mips::V1); |
230 | 1 | } |
231 | 246 | } |
232 | | |
233 | | // Adjust SP by FrameSize bytes. Restore RA, S0, S1 |
234 | | void Mips16InstrInfo::restoreFrame(unsigned SP, int64_t FrameSize, |
235 | | MachineBasicBlock &MBB, |
236 | 244 | MachineBasicBlock::iterator I) const { |
237 | 244 | DebugLoc DL = I != MBB.end() ? I->getDebugLoc()244 : DebugLoc()0 ; |
238 | 244 | MachineFunction *MF = MBB.getParent(); |
239 | 244 | MachineFrameInfo &MFI = MF->getFrameInfo(); |
240 | 244 | const BitVector Reserved = RI.getReservedRegs(*MF); |
241 | 244 | bool SaveS2 = Reserved[Mips::S2]; |
242 | 244 | MachineInstrBuilder MIB; |
243 | 240 | unsigned Opc = ((FrameSize <= 128) && !SaveS2)? |
244 | 244 | Mips::Restore16172 :Mips::RestoreX1672 ; |
245 | 244 | |
246 | 244 | if (!isUInt<11>(FrameSize)244 ) { |
247 | 1 | unsigned Base = 2040; |
248 | 1 | int64_t Remainder = FrameSize - Base; |
249 | 1 | FrameSize = Base; // should create template function like isUInt that |
250 | 1 | // returns largest possible n bit unsigned integer |
251 | 1 | |
252 | 1 | if (isInt<16>(Remainder)) |
253 | 1 | BuildAddiuSpImm(MBB, I, Remainder); |
254 | 1 | else |
255 | 0 | adjustStackPtrBig(SP, Remainder, MBB, I, Mips::A0, Mips::A1); |
256 | 1 | } |
257 | 244 | MIB = BuildMI(MBB, I, DL, get(Opc)); |
258 | 244 | const std::vector<CalleeSavedInfo> &CSI = MFI.getCalleeSavedInfo(); |
259 | 244 | addSaveRestoreRegs(MIB, CSI, RegState::Define); |
260 | 244 | if (SaveS2) |
261 | 69 | MIB.addReg(Mips::S2, RegState::Define); |
262 | 244 | MIB.addImm(FrameSize); |
263 | 244 | } |
264 | | |
265 | | // Adjust SP by Amount bytes where bytes can be up to 32bit number. |
266 | | // This can only be called at times that we know that there is at least one free |
267 | | // register. |
268 | | // This is clearly safe at prologue and epilogue. |
269 | | void Mips16InstrInfo::adjustStackPtrBig(unsigned SP, int64_t Amount, |
270 | | MachineBasicBlock &MBB, |
271 | | MachineBasicBlock::iterator I, |
272 | 0 | unsigned Reg1, unsigned Reg2) const { |
273 | 0 | DebugLoc DL; |
274 | 0 | // |
275 | 0 | // li reg1, constant |
276 | 0 | // move reg2, sp |
277 | 0 | // add reg1, reg1, reg2 |
278 | 0 | // move sp, reg1 |
279 | 0 | // |
280 | 0 | // |
281 | 0 | MachineInstrBuilder MIB1 = BuildMI(MBB, I, DL, get(Mips::LwConstant32), Reg1); |
282 | 0 | MIB1.addImm(Amount).addImm(-1); |
283 | 0 | MachineInstrBuilder MIB2 = BuildMI(MBB, I, DL, get(Mips::MoveR3216), Reg2); |
284 | 0 | MIB2.addReg(Mips::SP, RegState::Kill); |
285 | 0 | MachineInstrBuilder MIB3 = BuildMI(MBB, I, DL, get(Mips::AdduRxRyRz16), Reg1); |
286 | 0 | MIB3.addReg(Reg1); |
287 | 0 | MIB3.addReg(Reg2, RegState::Kill); |
288 | 0 | MachineInstrBuilder MIB4 = BuildMI(MBB, I, DL, get(Mips::Move32R16), |
289 | 0 | Mips::SP); |
290 | 0 | MIB4.addReg(Reg1, RegState::Kill); |
291 | 0 | } |
292 | | |
293 | | void Mips16InstrInfo::adjustStackPtrBigUnrestricted( |
294 | | unsigned SP, int64_t Amount, MachineBasicBlock &MBB, |
295 | 0 | MachineBasicBlock::iterator I) const { |
296 | 0 | llvm_unreachable("adjust stack pointer amount exceeded"); |
297 | 0 | } |
298 | | |
299 | | /// Adjust SP by Amount bytes. |
300 | | void Mips16InstrInfo::adjustStackPtr(unsigned SP, int64_t Amount, |
301 | | MachineBasicBlock &MBB, |
302 | 8 | MachineBasicBlock::iterator I) const { |
303 | 8 | if (Amount == 0) |
304 | 4 | return; |
305 | 4 | |
306 | 4 | if (4 isInt<16>(Amount)4 ) // need to change to addiu sp, ....and isInt<16> |
307 | 4 | BuildAddiuSpImm(MBB, I, Amount); |
308 | 4 | else |
309 | 0 | adjustStackPtrBigUnrestricted(SP, Amount, MBB, I); |
310 | 8 | } |
311 | | |
312 | | /// This function generates the sequence of instructions needed to get the |
313 | | /// result of adding register REG and immediate IMM. |
314 | | unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg, int64_t Imm, |
315 | | MachineBasicBlock &MBB, |
316 | | MachineBasicBlock::iterator II, |
317 | | const DebugLoc &DL, |
318 | 0 | unsigned &NewImm) const { |
319 | 0 | // |
320 | 0 | // given original instruction is: |
321 | 0 | // Instr rx, T[offset] where offset is too big. |
322 | 0 | // |
323 | 0 | // lo = offset & 0xFFFF |
324 | 0 | // hi = ((offset >> 16) + (lo >> 15)) & 0xFFFF; |
325 | 0 | // |
326 | 0 | // let T = temporary register |
327 | 0 | // li T, hi |
328 | 0 | // shl T, 16 |
329 | 0 | // add T, Rx, T |
330 | 0 | // |
331 | 0 | RegScavenger rs; |
332 | 0 | int32_t lo = Imm & 0xFFFF; |
333 | 0 | NewImm = lo; |
334 | 0 | int Reg =0; |
335 | 0 | int SpReg = 0; |
336 | 0 |
|
337 | 0 | rs.enterBasicBlock(MBB); |
338 | 0 | rs.forward(II); |
339 | 0 | // |
340 | 0 | // We need to know which registers can be used, in the case where there |
341 | 0 | // are not enough free registers. We exclude all registers that |
342 | 0 | // are used in the instruction that we are helping. |
343 | 0 | // // Consider all allocatable registers in the register class initially |
344 | 0 | BitVector Candidates = |
345 | 0 | RI.getAllocatableSet |
346 | 0 | (*II->getParent()->getParent(), &Mips::CPU16RegsRegClass); |
347 | 0 | // Exclude all the registers being used by the instruction. |
348 | 0 | for (unsigned i = 0, e = II->getNumOperands(); i != e0 ; ++i0 ) { |
349 | 0 | MachineOperand &MO = II->getOperand(i); |
350 | 0 | if (MO.isReg() && 0 MO.getReg() != 00 && !MO.isDef()0 && |
351 | 0 | !TargetRegisterInfo::isVirtualRegister(MO.getReg())) |
352 | 0 | Candidates.reset(MO.getReg()); |
353 | 0 | } |
354 | 0 |
|
355 | 0 | // If the same register was used and defined in an instruction, then |
356 | 0 | // it will not be in the list of candidates. |
357 | 0 | // |
358 | 0 | // we need to analyze the instruction that we are helping. |
359 | 0 | // we need to know if it defines register x but register x is not |
360 | 0 | // present as an operand of the instruction. this tells |
361 | 0 | // whether the register is live before the instruction. if it's not |
362 | 0 | // then we don't need to save it in case there are no free registers. |
363 | 0 | int DefReg = 0; |
364 | 0 | for (unsigned i = 0, e = II->getNumOperands(); i != e0 ; ++i0 ) { |
365 | 0 | MachineOperand &MO = II->getOperand(i); |
366 | 0 | if (MO.isReg() && 0 MO.isDef()0 ) { |
367 | 0 | DefReg = MO.getReg(); |
368 | 0 | break; |
369 | 0 | } |
370 | 0 | } |
371 | 0 |
|
372 | 0 | BitVector Available = rs.getRegsAvailable(&Mips::CPU16RegsRegClass); |
373 | 0 | Available &= Candidates; |
374 | 0 | // |
375 | 0 | // we use T0 for the first register, if we need to save something away. |
376 | 0 | // we use T1 for the second register, if we need to save something away. |
377 | 0 | // |
378 | 0 | unsigned FirstRegSaved =0, SecondRegSaved=0; |
379 | 0 | unsigned FirstRegSavedTo = 0, SecondRegSavedTo = 0; |
380 | 0 |
|
381 | 0 | Reg = Available.find_first(); |
382 | 0 |
|
383 | 0 | if (Reg == -10 ) { |
384 | 0 | Reg = Candidates.find_first(); |
385 | 0 | Candidates.reset(Reg); |
386 | 0 | if (DefReg != Reg0 ) { |
387 | 0 | FirstRegSaved = Reg; |
388 | 0 | FirstRegSavedTo = Mips::T0; |
389 | 0 | copyPhysReg(MBB, II, DL, FirstRegSavedTo, FirstRegSaved, true); |
390 | 0 | } |
391 | 0 | } |
392 | 0 | else |
393 | 0 | Available.reset(Reg); |
394 | 0 | BuildMI(MBB, II, DL, get(Mips::LwConstant32), Reg).addImm(Imm).addImm(-1); |
395 | 0 | NewImm = 0; |
396 | 0 | if (FrameReg == Mips::SP0 ) { |
397 | 0 | SpReg = Available.find_first(); |
398 | 0 | if (SpReg == -10 ) { |
399 | 0 | SpReg = Candidates.find_first(); |
400 | 0 | // Candidates.reset(SpReg); // not really needed |
401 | 0 | if (DefReg!= SpReg0 ) { |
402 | 0 | SecondRegSaved = SpReg; |
403 | 0 | SecondRegSavedTo = Mips::T1; |
404 | 0 | } |
405 | 0 | if (SecondRegSaved) |
406 | 0 | copyPhysReg(MBB, II, DL, SecondRegSavedTo, SecondRegSaved, true); |
407 | 0 | } |
408 | 0 | else |
409 | 0 | Available.reset(SpReg); |
410 | 0 | copyPhysReg(MBB, II, DL, SpReg, Mips::SP, false); |
411 | 0 | BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(SpReg, RegState::Kill) |
412 | 0 | .addReg(Reg); |
413 | 0 | } |
414 | 0 | else |
415 | 0 | BuildMI(MBB, II, DL, get(Mips:: AdduRxRyRz16), Reg).addReg(FrameReg) |
416 | 0 | .addReg(Reg, RegState::Kill); |
417 | 0 | if (FirstRegSaved || 0 SecondRegSaved0 ) { |
418 | 0 | II = std::next(II); |
419 | 0 | if (FirstRegSaved) |
420 | 0 | copyPhysReg(MBB, II, DL, FirstRegSaved, FirstRegSavedTo, true); |
421 | 0 | if (SecondRegSaved) |
422 | 0 | copyPhysReg(MBB, II, DL, SecondRegSaved, SecondRegSavedTo, true); |
423 | 0 | } |
424 | 0 | return Reg; |
425 | 0 | } |
426 | | |
427 | 9.68k | unsigned Mips16InstrInfo::getAnalyzableBrOpc(unsigned Opc) const { |
428 | 9.68k | return (Opc == Mips::BeqzRxImmX16 || Opc == Mips::BimmX16 || |
429 | 9.68k | Opc == Mips::Bimm16 || |
430 | 9.68k | Opc == Mips::Bteqz168.37k || Opc == Mips::Btnez167.60k || |
431 | 9.68k | Opc == Mips::BeqzRxImm166.67k || Opc == Mips::BnezRxImm166.52k || |
432 | 9.68k | Opc == Mips::BnezRxImmX165.85k || Opc == Mips::BteqzX165.85k || |
433 | 9.68k | Opc == Mips::BteqzT8CmpX165.85k || Opc == Mips::BteqzT8CmpiX165.85k || |
434 | 9.68k | Opc == Mips::BteqzT8SltX165.85k || Opc == Mips::BteqzT8SltuX165.85k || |
435 | 9.68k | Opc == Mips::BteqzT8SltiX165.85k || Opc == Mips::BteqzT8SltiuX165.85k || |
436 | 9.68k | Opc == Mips::BtnezX165.85k || Opc == Mips::BtnezT8CmpX165.85k || |
437 | 9.68k | Opc == Mips::BtnezT8CmpiX165.85k || Opc == Mips::BtnezT8SltX165.85k || |
438 | 9.68k | Opc == Mips::BtnezT8SltuX165.85k || Opc == Mips::BtnezT8SltiX165.85k || |
439 | 9.68k | Opc == Mips::BtnezT8SltiuX165.85k ) ? Opc3.83k : 05.85k ; |
440 | 9.68k | } |
441 | | |
442 | | void Mips16InstrInfo::ExpandRetRA16(MachineBasicBlock &MBB, |
443 | | MachineBasicBlock::iterator I, |
444 | 380 | unsigned Opc) const { |
445 | 380 | BuildMI(MBB, I, I->getDebugLoc(), get(Opc)); |
446 | 380 | } |
447 | | |
448 | 6 | const MCInstrDesc &Mips16InstrInfo::AddiuSpImm(int64_t Imm) const { |
449 | 6 | if (validSpImm8(Imm)) |
450 | 6 | return get(Mips::AddiuSpImm16); |
451 | 6 | else |
452 | 0 | return get(Mips::AddiuSpImmX16); |
453 | 0 | } |
454 | | |
455 | | void Mips16InstrInfo::BuildAddiuSpImm |
456 | 6 | (MachineBasicBlock &MBB, MachineBasicBlock::iterator I, int64_t Imm) const { |
457 | 6 | DebugLoc DL; |
458 | 6 | BuildMI(MBB, I, DL, AddiuSpImm(Imm)).addImm(Imm); |
459 | 6 | } |
460 | | |
461 | 2.37k | const MipsInstrInfo *llvm::createMips16InstrInfo(const MipsSubtarget &STI) { |
462 | 2.37k | return new Mips16InstrInfo(STI); |
463 | 2.37k | } |
464 | | |
465 | | bool Mips16InstrInfo::validImmediate(unsigned Opcode, unsigned Reg, |
466 | 1.12k | int64_t Amount) { |
467 | 1.12k | switch (Opcode) { |
468 | 1.11k | case Mips::LbRxRyOffMemX16: |
469 | 1.11k | case Mips::LbuRxRyOffMemX16: |
470 | 1.11k | case Mips::LhRxRyOffMemX16: |
471 | 1.11k | case Mips::LhuRxRyOffMemX16: |
472 | 1.11k | case Mips::SbRxRyOffMemX16: |
473 | 1.11k | case Mips::ShRxRyOffMemX16: |
474 | 1.11k | case Mips::LwRxRyOffMemX16: |
475 | 1.11k | case Mips::SwRxRyOffMemX16: |
476 | 1.11k | case Mips::SwRxSpImmX16: |
477 | 1.11k | case Mips::LwRxSpImmX16: |
478 | 1.11k | return isInt<16>(Amount); |
479 | 11 | case Mips::AddiuRxRyOffMemX16: |
480 | 11 | if ((Reg == Mips::PC) || 11 (Reg == Mips::SP)11 ) |
481 | 7 | return isInt<16>(Amount); |
482 | 4 | return isInt<15>(Amount); |
483 | 0 | } |
484 | 0 | llvm_unreachable0 ("unexpected Opcode in validImmediate"); |
485 | 0 | } |