blob: 6f634b380a9b701278143f597a3083fa1545f8cf [file] [log] [blame]
Evan Chengb9803a82009-11-06 23:52:48 +00001//===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -----*- C++ -*-=//
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 a pass that expand pseudo instructions into target
11// instructions to allow proper scheduling, if-conversion, and other late
12// optimizations. This pass should be run after register allocation but before
13// post- regalloc scheduling pass.
14//
15//===----------------------------------------------------------------------===//
16
17#define DEBUG_TYPE "arm-pseudo"
18#include "ARM.h"
19#include "ARMBaseInstrInfo.h"
20#include "llvm/CodeGen/MachineFunctionPass.h"
21#include "llvm/CodeGen/MachineInstrBuilder.h"
Chris Lattner4dbbe342010-07-20 21:17:29 +000022#include "llvm/Target/TargetRegisterInfo.h"
Evan Chengb9803a82009-11-06 23:52:48 +000023using namespace llvm;
24
25namespace {
26 class ARMExpandPseudo : public MachineFunctionPass {
Bob Wilson709d5922010-08-25 23:27:42 +000027 // Constants for register spacing in NEON load/store instructions.
28 enum NEONRegSpacing {
29 SingleSpc,
30 EvenDblSpc,
31 OddDblSpc
32 };
33
Evan Chengb9803a82009-11-06 23:52:48 +000034 public:
35 static char ID;
Owen Anderson90c579d2010-08-06 18:33:48 +000036 ARMExpandPseudo() : MachineFunctionPass(ID) {}
Evan Chengb9803a82009-11-06 23:52:48 +000037
38 const TargetInstrInfo *TII;
Evan Chengd929f772010-05-13 00:17:02 +000039 const TargetRegisterInfo *TRI;
Evan Chengb9803a82009-11-06 23:52:48 +000040
41 virtual bool runOnMachineFunction(MachineFunction &Fn);
42
43 virtual const char *getPassName() const {
44 return "ARM pseudo instruction expansion pass";
45 }
46
47 private:
Evan Cheng43130072010-05-12 23:13:12 +000048 void TransferImpOps(MachineInstr &OldMI,
49 MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI);
Evan Chengb9803a82009-11-06 23:52:48 +000050 bool ExpandMBB(MachineBasicBlock &MBB);
Bob Wilsonffde0802010-09-02 16:00:54 +000051 void ExpandVLD(MachineBasicBlock::iterator &MBBI, unsigned Opc,
52 bool hasWriteBack, NEONRegSpacing RegSpc, unsigned NumRegs);
Bob Wilson01ba4612010-08-26 18:51:29 +000053 void ExpandVST(MachineBasicBlock::iterator &MBBI, unsigned Opc,
54 bool hasWriteBack, NEONRegSpacing RegSpc, unsigned NumRegs);
Evan Chengb9803a82009-11-06 23:52:48 +000055 };
56 char ARMExpandPseudo::ID = 0;
57}
58
Evan Cheng43130072010-05-12 23:13:12 +000059/// TransferImpOps - Transfer implicit operands on the pseudo instruction to
60/// the instructions created from the expansion.
61void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI,
62 MachineInstrBuilder &UseMI,
63 MachineInstrBuilder &DefMI) {
64 const TargetInstrDesc &Desc = OldMI.getDesc();
65 for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands();
66 i != e; ++i) {
67 const MachineOperand &MO = OldMI.getOperand(i);
68 assert(MO.isReg() && MO.getReg());
69 if (MO.isUse())
70 UseMI.addReg(MO.getReg(), getKillRegState(MO.isKill()));
71 else
72 DefMI.addReg(MO.getReg(),
73 getDefRegState(true) | getDeadRegState(MO.isDead()));
74 }
75}
76
Bob Wilson82a9c842010-09-02 16:17:29 +000077/// ExpandVLD - Translate VLD pseudo instructions with Q, QQ or QQQQ register
78/// operands to real VLD instructions with D register operands.
Bob Wilsonffde0802010-09-02 16:00:54 +000079void ARMExpandPseudo::ExpandVLD(MachineBasicBlock::iterator &MBBI,
80 unsigned Opc, bool hasWriteBack,
81 NEONRegSpacing RegSpc, unsigned NumRegs) {
82 MachineInstr &MI = *MBBI;
83 MachineBasicBlock &MBB = *MI.getParent();
84
85 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc));
86 unsigned OpIdx = 0;
87
88 bool DstIsDead = MI.getOperand(OpIdx).isDead();
89 unsigned DstReg = MI.getOperand(OpIdx++).getReg();
90 unsigned D0, D1, D2, D3;
91 if (RegSpc == SingleSpc) {
92 D0 = TRI->getSubReg(DstReg, ARM::dsub_0);
93 D1 = TRI->getSubReg(DstReg, ARM::dsub_1);
94 D2 = TRI->getSubReg(DstReg, ARM::dsub_2);
95 D3 = TRI->getSubReg(DstReg, ARM::dsub_3);
96 } else if (RegSpc == EvenDblSpc) {
97 D0 = TRI->getSubReg(DstReg, ARM::dsub_0);
98 D1 = TRI->getSubReg(DstReg, ARM::dsub_2);
99 D2 = TRI->getSubReg(DstReg, ARM::dsub_4);
100 D3 = TRI->getSubReg(DstReg, ARM::dsub_6);
101 } else {
102 assert(RegSpc == OddDblSpc && "unknown register spacing for VLD");
103 D0 = TRI->getSubReg(DstReg, ARM::dsub_1);
104 D1 = TRI->getSubReg(DstReg, ARM::dsub_3);
105 D2 = TRI->getSubReg(DstReg, ARM::dsub_5);
106 D3 = TRI->getSubReg(DstReg, ARM::dsub_7);
107 }
108 MIB.addReg(D0).addReg(D1);
109 if (NumRegs > 2)
110 MIB.addReg(D2);
111 if (NumRegs > 3)
112 MIB.addReg(D3);
113
114 if (hasWriteBack) {
115 bool WBIsDead = MI.getOperand(OpIdx).isDead();
116 unsigned WBReg = MI.getOperand(OpIdx++).getReg();
117 MIB.addReg(WBReg, getDefRegState(true) | getDeadRegState(WBIsDead));
118 }
119 // Copy the addrmode6 operands.
120 bool AddrIsKill = MI.getOperand(OpIdx).isKill();
121 MIB.addReg(MI.getOperand(OpIdx++).getReg(), getKillRegState(AddrIsKill));
122 MIB.addImm(MI.getOperand(OpIdx++).getImm());
123 if (hasWriteBack) {
124 // Copy the am6offset operand.
125 bool OffsetIsKill = MI.getOperand(OpIdx).isKill();
126 MIB.addReg(MI.getOperand(OpIdx++).getReg(), getKillRegState(OffsetIsKill));
127 }
128
129 MIB = AddDefaultPred(MIB);
130 TransferImpOps(MI, MIB, MIB);
131 // Add an implicit def for the super-reg.
132 MIB.addReg(DstReg, (getDefRegState(true) | getDeadRegState(DstIsDead) |
133 getImplRegState(true)));
134 MI.eraseFromParent();
135}
136
Bob Wilson01ba4612010-08-26 18:51:29 +0000137/// ExpandVST - Translate VST pseudo instructions with Q, QQ or QQQQ register
138/// operands to real VST instructions with D register operands.
139void ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator &MBBI,
140 unsigned Opc, bool hasWriteBack,
141 NEONRegSpacing RegSpc, unsigned NumRegs) {
Bob Wilson709d5922010-08-25 23:27:42 +0000142 MachineInstr &MI = *MBBI;
143 MachineBasicBlock &MBB = *MI.getParent();
144
145 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc));
146 unsigned OpIdx = 0;
147 if (hasWriteBack) {
148 bool DstIsDead = MI.getOperand(OpIdx).isDead();
149 unsigned DstReg = MI.getOperand(OpIdx++).getReg();
150 MIB.addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead));
151 }
152 // Copy the addrmode6 operands.
153 bool AddrIsKill = MI.getOperand(OpIdx).isKill();
154 MIB.addReg(MI.getOperand(OpIdx++).getReg(), getKillRegState(AddrIsKill));
155 MIB.addImm(MI.getOperand(OpIdx++).getImm());
156 if (hasWriteBack) {
157 // Copy the am6offset operand.
158 bool OffsetIsKill = MI.getOperand(OpIdx).isKill();
159 MIB.addReg(MI.getOperand(OpIdx++).getReg(), getKillRegState(OffsetIsKill));
160 }
161
162 bool SrcIsKill = MI.getOperand(OpIdx).isKill();
163 unsigned SrcReg = MI.getOperand(OpIdx).getReg();
164 unsigned D0, D1, D2, D3;
165 if (RegSpc == SingleSpc) {
166 D0 = TRI->getSubReg(SrcReg, ARM::dsub_0);
167 D1 = TRI->getSubReg(SrcReg, ARM::dsub_1);
168 D2 = TRI->getSubReg(SrcReg, ARM::dsub_2);
169 D3 = TRI->getSubReg(SrcReg, ARM::dsub_3);
170 } else if (RegSpc == EvenDblSpc) {
171 D0 = TRI->getSubReg(SrcReg, ARM::dsub_0);
172 D1 = TRI->getSubReg(SrcReg, ARM::dsub_2);
173 D2 = TRI->getSubReg(SrcReg, ARM::dsub_4);
174 D3 = TRI->getSubReg(SrcReg, ARM::dsub_6);
175 } else {
Bob Wilson01ba4612010-08-26 18:51:29 +0000176 assert(RegSpc == OddDblSpc && "unknown register spacing for VST");
Bob Wilson709d5922010-08-25 23:27:42 +0000177 D0 = TRI->getSubReg(SrcReg, ARM::dsub_1);
178 D1 = TRI->getSubReg(SrcReg, ARM::dsub_3);
179 D2 = TRI->getSubReg(SrcReg, ARM::dsub_5);
180 D3 = TRI->getSubReg(SrcReg, ARM::dsub_7);
181 }
182
Bob Wilson7e701972010-08-30 18:10:48 +0000183 MIB.addReg(D0).addReg(D1);
Bob Wilsone5ce4f62010-08-28 05:12:57 +0000184 if (NumRegs > 2)
Bob Wilson7e701972010-08-30 18:10:48 +0000185 MIB.addReg(D2);
Bob Wilson01ba4612010-08-26 18:51:29 +0000186 if (NumRegs > 3)
Bob Wilson7e701972010-08-30 18:10:48 +0000187 MIB.addReg(D3);
Bob Wilson709d5922010-08-25 23:27:42 +0000188 MIB = AddDefaultPred(MIB);
189 TransferImpOps(MI, MIB, MIB);
Bob Wilson7e701972010-08-30 18:10:48 +0000190 if (SrcIsKill)
191 // Add an implicit kill for the super-reg.
192 (*MIB).addRegisterKilled(SrcReg, TRI, true);
Bob Wilson709d5922010-08-25 23:27:42 +0000193 MI.eraseFromParent();
194}
195
Evan Chengb9803a82009-11-06 23:52:48 +0000196bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
197 bool Modified = false;
198
199 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
200 while (MBBI != E) {
201 MachineInstr &MI = *MBBI;
Chris Lattner7896c9f2009-12-03 00:50:42 +0000202 MachineBasicBlock::iterator NMBBI = llvm::next(MBBI);
Evan Chengb9803a82009-11-06 23:52:48 +0000203
Bob Wilson709d5922010-08-25 23:27:42 +0000204 bool ModifiedOp = true;
Evan Chengb9803a82009-11-06 23:52:48 +0000205 unsigned Opcode = MI.getOpcode();
206 switch (Opcode) {
Bob Wilson709d5922010-08-25 23:27:42 +0000207 default:
208 ModifiedOp = false;
209 break;
210
Evan Chengb9803a82009-11-06 23:52:48 +0000211 case ARM::tLDRpci_pic:
212 case ARM::t2LDRpci_pic: {
213 unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
214 ? ARM::tLDRpci : ARM::t2LDRpci;
215 unsigned DstReg = MI.getOperand(0).getReg();
Evan Cheng43130072010-05-12 23:13:12 +0000216 bool DstIsDead = MI.getOperand(0).isDead();
217 MachineInstrBuilder MIB1 =
218 AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
219 TII->get(NewLdOpc), DstReg)
220 .addOperand(MI.getOperand(1)));
221 (*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
222 MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
223 TII->get(ARM::tPICADD))
224 .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
225 .addReg(DstReg)
226 .addOperand(MI.getOperand(2));
227 TransferImpOps(MI, MIB1, MIB2);
Evan Chengb9803a82009-11-06 23:52:48 +0000228 MI.eraseFromParent();
Evan Chengb9803a82009-11-06 23:52:48 +0000229 break;
230 }
Evan Cheng43130072010-05-12 23:13:12 +0000231
Anton Korobeynikov6d1e29d2010-08-30 22:50:36 +0000232 case ARM::MOVi32imm:
Evan Chengb9803a82009-11-06 23:52:48 +0000233 case ARM::t2MOVi32imm: {
Evan Cheng43130072010-05-12 23:13:12 +0000234 unsigned PredReg = 0;
235 ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg);
Evan Chengb9803a82009-11-06 23:52:48 +0000236 unsigned DstReg = MI.getOperand(0).getReg();
Evan Cheng43130072010-05-12 23:13:12 +0000237 bool DstIsDead = MI.getOperand(0).isDead();
238 const MachineOperand &MO = MI.getOperand(1);
239 MachineInstrBuilder LO16, HI16;
Anton Korobeynikov5cdc3a92009-11-24 00:44:37 +0000240
Anton Korobeynikov6d1e29d2010-08-30 22:50:36 +0000241 LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
242 TII->get(Opcode == ARM::MOVi32imm ?
243 ARM::MOVi16 : ARM::t2MOVi16),
Evan Cheng43130072010-05-12 23:13:12 +0000244 DstReg);
Anton Korobeynikov6d1e29d2010-08-30 22:50:36 +0000245 HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
246 TII->get(Opcode == ARM::MOVi32imm ?
247 ARM::MOVTi16 : ARM::t2MOVTi16))
Evan Cheng43130072010-05-12 23:13:12 +0000248 .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead))
249 .addReg(DstReg);
Anton Korobeynikov5cdc3a92009-11-24 00:44:37 +0000250
Evan Cheng43130072010-05-12 23:13:12 +0000251 if (MO.isImm()) {
252 unsigned Imm = MO.getImm();
253 unsigned Lo16 = Imm & 0xffff;
254 unsigned Hi16 = (Imm >> 16) & 0xffff;
255 LO16 = LO16.addImm(Lo16);
256 HI16 = HI16.addImm(Hi16);
257 } else {
258 const GlobalValue *GV = MO.getGlobal();
259 unsigned TF = MO.getTargetFlags();
260 LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
261 HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
Evan Chengb9803a82009-11-06 23:52:48 +0000262 }
Evan Cheng43130072010-05-12 23:13:12 +0000263 (*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
264 (*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
265 LO16.addImm(Pred).addReg(PredReg);
266 HI16.addImm(Pred).addReg(PredReg);
267 TransferImpOps(MI, LO16, HI16);
Evan Chengb9803a82009-11-06 23:52:48 +0000268 MI.eraseFromParent();
Evan Chengd929f772010-05-13 00:17:02 +0000269 break;
270 }
271
272 case ARM::VMOVQQ: {
273 unsigned DstReg = MI.getOperand(0).getReg();
274 bool DstIsDead = MI.getOperand(0).isDead();
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000275 unsigned EvenDst = TRI->getSubReg(DstReg, ARM::qsub_0);
276 unsigned OddDst = TRI->getSubReg(DstReg, ARM::qsub_1);
Evan Chengd929f772010-05-13 00:17:02 +0000277 unsigned SrcReg = MI.getOperand(1).getReg();
278 bool SrcIsKill = MI.getOperand(1).isKill();
Jakob Stoklund Olesen558661d2010-05-24 16:54:32 +0000279 unsigned EvenSrc = TRI->getSubReg(SrcReg, ARM::qsub_0);
280 unsigned OddSrc = TRI->getSubReg(SrcReg, ARM::qsub_1);
Evan Chengd929f772010-05-13 00:17:02 +0000281 MachineInstrBuilder Even =
282 AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
283 TII->get(ARM::VMOVQ))
Jim Grosbach18f30e62010-06-02 21:53:11 +0000284 .addReg(EvenDst,
285 getDefRegState(true) | getDeadRegState(DstIsDead))
286 .addReg(EvenSrc, getKillRegState(SrcIsKill)));
Evan Chengd929f772010-05-13 00:17:02 +0000287 MachineInstrBuilder Odd =
288 AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
289 TII->get(ARM::VMOVQ))
Jim Grosbach18f30e62010-06-02 21:53:11 +0000290 .addReg(OddDst,
291 getDefRegState(true) | getDeadRegState(DstIsDead))
292 .addReg(OddSrc, getKillRegState(SrcIsKill)));
Evan Chengd929f772010-05-13 00:17:02 +0000293 TransferImpOps(MI, Even, Odd);
294 MI.eraseFromParent();
Bob Wilson709d5922010-08-25 23:27:42 +0000295 }
296
Bob Wilsonffde0802010-09-02 16:00:54 +0000297 case ARM::VLD1q8Pseudo:
298 ExpandVLD(MBBI, ARM::VLD1q8, false, SingleSpc, 2); break;
299 case ARM::VLD1q16Pseudo:
300 ExpandVLD(MBBI, ARM::VLD1q16, false, SingleSpc, 2); break;
301 case ARM::VLD1q32Pseudo:
302 ExpandVLD(MBBI, ARM::VLD1q32, false, SingleSpc, 2); break;
303 case ARM::VLD1q64Pseudo:
304 ExpandVLD(MBBI, ARM::VLD1q64, false, SingleSpc, 2); break;
305 case ARM::VLD1q8Pseudo_UPD:
306 ExpandVLD(MBBI, ARM::VLD1q8, true, SingleSpc, 2); break;
307 case ARM::VLD1q16Pseudo_UPD:
308 ExpandVLD(MBBI, ARM::VLD1q16, true, SingleSpc, 2); break;
309 case ARM::VLD1q32Pseudo_UPD:
310 ExpandVLD(MBBI, ARM::VLD1q32, true, SingleSpc, 2); break;
311 case ARM::VLD1q64Pseudo_UPD:
312 ExpandVLD(MBBI, ARM::VLD1q64, true, SingleSpc, 2); break;
313
314 case ARM::VLD2d8Pseudo:
315 ExpandVLD(MBBI, ARM::VLD2d8, false, SingleSpc, 2); break;
316 case ARM::VLD2d16Pseudo:
317 ExpandVLD(MBBI, ARM::VLD2d16, false, SingleSpc, 2); break;
318 case ARM::VLD2d32Pseudo:
319 ExpandVLD(MBBI, ARM::VLD2d32, false, SingleSpc, 2); break;
320 case ARM::VLD2q8Pseudo:
321 ExpandVLD(MBBI, ARM::VLD2q8, false, SingleSpc, 4); break;
322 case ARM::VLD2q16Pseudo:
323 ExpandVLD(MBBI, ARM::VLD2q16, false, SingleSpc, 4); break;
324 case ARM::VLD2q32Pseudo:
325 ExpandVLD(MBBI, ARM::VLD2q32, false, SingleSpc, 4); break;
326 case ARM::VLD2d8Pseudo_UPD:
327 ExpandVLD(MBBI, ARM::VLD2d8, true, SingleSpc, 2); break;
328 case ARM::VLD2d16Pseudo_UPD:
329 ExpandVLD(MBBI, ARM::VLD2d16, true, SingleSpc, 2); break;
330 case ARM::VLD2d32Pseudo_UPD:
331 ExpandVLD(MBBI, ARM::VLD2d32, true, SingleSpc, 2); break;
332 case ARM::VLD2q8Pseudo_UPD:
333 ExpandVLD(MBBI, ARM::VLD2q8, true, SingleSpc, 4); break;
334 case ARM::VLD2q16Pseudo_UPD:
335 ExpandVLD(MBBI, ARM::VLD2q16, true, SingleSpc, 4); break;
336 case ARM::VLD2q32Pseudo_UPD:
337 ExpandVLD(MBBI, ARM::VLD2q32, true, SingleSpc, 4); break;
338
339 case ARM::VLD1d64TPseudo:
340 ExpandVLD(MBBI, ARM::VLD1d64T, false, SingleSpc, 3); break;
341 case ARM::VLD1d64TPseudo_UPD:
342 ExpandVLD(MBBI, ARM::VLD1d64T, true, SingleSpc, 3); break;
343
344 case ARM::VLD1d64QPseudo:
345 ExpandVLD(MBBI, ARM::VLD1d64Q, false, SingleSpc, 4); break;
346 case ARM::VLD1d64QPseudo_UPD:
347 ExpandVLD(MBBI, ARM::VLD1d64Q, true, SingleSpc, 4); break;
348
Bob Wilsone5ce4f62010-08-28 05:12:57 +0000349 case ARM::VST1q8Pseudo:
350 ExpandVST(MBBI, ARM::VST1q8, false, SingleSpc, 2); break;
351 case ARM::VST1q16Pseudo:
352 ExpandVST(MBBI, ARM::VST1q16, false, SingleSpc, 2); break;
353 case ARM::VST1q32Pseudo:
354 ExpandVST(MBBI, ARM::VST1q32, false, SingleSpc, 2); break;
355 case ARM::VST1q64Pseudo:
356 ExpandVST(MBBI, ARM::VST1q64, false, SingleSpc, 2); break;
357 case ARM::VST1q8Pseudo_UPD:
358 ExpandVST(MBBI, ARM::VST1q8_UPD, true, SingleSpc, 2); break;
359 case ARM::VST1q16Pseudo_UPD:
360 ExpandVST(MBBI, ARM::VST1q16_UPD, true, SingleSpc, 2); break;
361 case ARM::VST1q32Pseudo_UPD:
362 ExpandVST(MBBI, ARM::VST1q32_UPD, true, SingleSpc, 2); break;
363 case ARM::VST1q64Pseudo_UPD:
364 ExpandVST(MBBI, ARM::VST1q64_UPD, true, SingleSpc, 2); break;
365
366 case ARM::VST2d8Pseudo:
367 ExpandVST(MBBI, ARM::VST2d8, false, SingleSpc, 2); break;
368 case ARM::VST2d16Pseudo:
369 ExpandVST(MBBI, ARM::VST2d16, false, SingleSpc, 2); break;
370 case ARM::VST2d32Pseudo:
371 ExpandVST(MBBI, ARM::VST2d32, false, SingleSpc, 2); break;
372 case ARM::VST2q8Pseudo:
373 ExpandVST(MBBI, ARM::VST2q8, false, SingleSpc, 4); break;
374 case ARM::VST2q16Pseudo:
375 ExpandVST(MBBI, ARM::VST2q16, false, SingleSpc, 4); break;
376 case ARM::VST2q32Pseudo:
377 ExpandVST(MBBI, ARM::VST2q32, false, SingleSpc, 4); break;
378 case ARM::VST2d8Pseudo_UPD:
379 ExpandVST(MBBI, ARM::VST2d8_UPD, true, SingleSpc, 2); break;
380 case ARM::VST2d16Pseudo_UPD:
381 ExpandVST(MBBI, ARM::VST2d16_UPD, true, SingleSpc, 2); break;
382 case ARM::VST2d32Pseudo_UPD:
383 ExpandVST(MBBI, ARM::VST2d32_UPD, true, SingleSpc, 2); break;
384 case ARM::VST2q8Pseudo_UPD:
385 ExpandVST(MBBI, ARM::VST2q8_UPD, true, SingleSpc, 4); break;
386 case ARM::VST2q16Pseudo_UPD:
387 ExpandVST(MBBI, ARM::VST2q16_UPD, true, SingleSpc, 4); break;
388 case ARM::VST2q32Pseudo_UPD:
389 ExpandVST(MBBI, ARM::VST2q32_UPD, true, SingleSpc, 4); break;
390
Bob Wilson01ba4612010-08-26 18:51:29 +0000391 case ARM::VST3d8Pseudo:
392 ExpandVST(MBBI, ARM::VST3d8, false, SingleSpc, 3); break;
393 case ARM::VST3d16Pseudo:
394 ExpandVST(MBBI, ARM::VST3d16, false, SingleSpc, 3); break;
395 case ARM::VST3d32Pseudo:
396 ExpandVST(MBBI, ARM::VST3d32, false, SingleSpc, 3); break;
397 case ARM::VST1d64TPseudo:
398 ExpandVST(MBBI, ARM::VST1d64T, false, SingleSpc, 3); break;
399 case ARM::VST3d8Pseudo_UPD:
400 ExpandVST(MBBI, ARM::VST3d8_UPD, true, SingleSpc, 3); break;
401 case ARM::VST3d16Pseudo_UPD:
402 ExpandVST(MBBI, ARM::VST3d16_UPD, true, SingleSpc, 3); break;
403 case ARM::VST3d32Pseudo_UPD:
404 ExpandVST(MBBI, ARM::VST3d32_UPD, true, SingleSpc, 3); break;
405 case ARM::VST1d64TPseudo_UPD:
406 ExpandVST(MBBI, ARM::VST1d64T_UPD, true, SingleSpc, 3); break;
407 case ARM::VST3q8Pseudo_UPD:
408 ExpandVST(MBBI, ARM::VST3q8_UPD, true, EvenDblSpc, 3); break;
409 case ARM::VST3q16Pseudo_UPD:
410 ExpandVST(MBBI, ARM::VST3q16_UPD, true, EvenDblSpc, 3); break;
411 case ARM::VST3q32Pseudo_UPD:
412 ExpandVST(MBBI, ARM::VST3q32_UPD, true, EvenDblSpc, 3); break;
413 case ARM::VST3q8oddPseudo_UPD:
414 ExpandVST(MBBI, ARM::VST3q8_UPD, true, OddDblSpc, 3); break;
415 case ARM::VST3q16oddPseudo_UPD:
416 ExpandVST(MBBI, ARM::VST3q16_UPD, true, OddDblSpc, 3); break;
417 case ARM::VST3q32oddPseudo_UPD:
418 ExpandVST(MBBI, ARM::VST3q32_UPD, true, OddDblSpc, 3); break;
419
Bob Wilson709d5922010-08-25 23:27:42 +0000420 case ARM::VST4d8Pseudo:
Bob Wilson01ba4612010-08-26 18:51:29 +0000421 ExpandVST(MBBI, ARM::VST4d8, false, SingleSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000422 case ARM::VST4d16Pseudo:
Bob Wilson01ba4612010-08-26 18:51:29 +0000423 ExpandVST(MBBI, ARM::VST4d16, false, SingleSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000424 case ARM::VST4d32Pseudo:
Bob Wilson01ba4612010-08-26 18:51:29 +0000425 ExpandVST(MBBI, ARM::VST4d32, false, SingleSpc, 4); break;
Bob Wilson70e48b22010-08-26 05:33:30 +0000426 case ARM::VST1d64QPseudo:
Bob Wilson01ba4612010-08-26 18:51:29 +0000427 ExpandVST(MBBI, ARM::VST1d64Q, false, SingleSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000428 case ARM::VST4d8Pseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000429 ExpandVST(MBBI, ARM::VST4d8_UPD, true, SingleSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000430 case ARM::VST4d16Pseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000431 ExpandVST(MBBI, ARM::VST4d16_UPD, true, SingleSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000432 case ARM::VST4d32Pseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000433 ExpandVST(MBBI, ARM::VST4d32_UPD, true, SingleSpc, 4); break;
Bob Wilson70e48b22010-08-26 05:33:30 +0000434 case ARM::VST1d64QPseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000435 ExpandVST(MBBI, ARM::VST1d64Q_UPD, true, SingleSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000436 case ARM::VST4q8Pseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000437 ExpandVST(MBBI, ARM::VST4q8_UPD, true, EvenDblSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000438 case ARM::VST4q16Pseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000439 ExpandVST(MBBI, ARM::VST4q16_UPD, true, EvenDblSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000440 case ARM::VST4q32Pseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000441 ExpandVST(MBBI, ARM::VST4q32_UPD, true, EvenDblSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000442 case ARM::VST4q8oddPseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000443 ExpandVST(MBBI, ARM::VST4q8_UPD, true, OddDblSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000444 case ARM::VST4q16oddPseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000445 ExpandVST(MBBI, ARM::VST4q16_UPD, true, OddDblSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000446 case ARM::VST4q32oddPseudo_UPD:
Bob Wilson01ba4612010-08-26 18:51:29 +0000447 ExpandVST(MBBI, ARM::VST4q32_UPD, true, OddDblSpc, 4); break;
Bob Wilson709d5922010-08-25 23:27:42 +0000448 }
449
450 if (ModifiedOp)
Evan Chengd929f772010-05-13 00:17:02 +0000451 Modified = true;
Evan Chengb9803a82009-11-06 23:52:48 +0000452 MBBI = NMBBI;
453 }
454
455 return Modified;
456}
457
458bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
459 TII = MF.getTarget().getInstrInfo();
Evan Chengd929f772010-05-13 00:17:02 +0000460 TRI = MF.getTarget().getRegisterInfo();
Evan Chengb9803a82009-11-06 23:52:48 +0000461
462 bool Modified = false;
463 for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
464 ++MFI)
465 Modified |= ExpandMBB(*MFI);
466 return Modified;
467}
468
469/// createARMExpandPseudoPass - returns an instance of the pseudo instruction
470/// expansion pass.
471FunctionPass *llvm::createARMExpandPseudoPass() {
472 return new ARMExpandPseudo();
473}