1 //===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -----*- C++ -*-=//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains a pass that expands 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 // the post-regalloc scheduling pass.
15 //===----------------------------------------------------------------------===//
17 #define DEBUG_TYPE "arm-pseudo"
19 #include "ARMAddressingModes.h"
20 #include "ARMBaseInstrInfo.h"
21 #include "ARMBaseRegisterInfo.h"
22 #include "ARMMachineFunctionInfo.h"
23 #include "ARMRegisterInfo.h"
24 #include "llvm/CodeGen/MachineFrameInfo.h"
25 #include "llvm/CodeGen/MachineFunctionPass.h"
26 #include "llvm/CodeGen/MachineInstrBuilder.h"
27 #include "llvm/Target/TargetRegisterInfo.h"
28 #include "llvm/Support/raw_ostream.h" // FIXME: for debug only. remove!
32 class ARMExpandPseudo
: public MachineFunctionPass
{
35 ARMExpandPseudo() : MachineFunctionPass(ID
) {}
37 const ARMBaseInstrInfo
*TII
;
38 const TargetRegisterInfo
*TRI
;
40 virtual bool runOnMachineFunction(MachineFunction
&Fn
);
42 virtual const char *getPassName() const {
43 return "ARM pseudo instruction expansion pass";
47 void TransferImpOps(MachineInstr
&OldMI
,
48 MachineInstrBuilder
&UseMI
, MachineInstrBuilder
&DefMI
);
49 bool ExpandMBB(MachineBasicBlock
&MBB
);
50 void ExpandVLD(MachineBasicBlock::iterator
&MBBI
);
51 void ExpandVST(MachineBasicBlock::iterator
&MBBI
);
52 void ExpandLaneOp(MachineBasicBlock::iterator
&MBBI
);
53 void ExpandVTBL(MachineBasicBlock::iterator
&MBBI
,
54 unsigned Opc
, bool IsExt
, unsigned NumRegs
);
56 char ARMExpandPseudo::ID
= 0;
59 /// TransferImpOps - Transfer implicit operands on the pseudo instruction to
60 /// the instructions created from the expansion.
61 void 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();
67 const MachineOperand
&MO
= OldMI
.getOperand(i
);
68 assert(MO
.isReg() && MO
.getReg());
77 // Constants for register spacing in NEON load/store instructions.
78 // For quad-register load-lane and store-lane pseudo instructors, the
79 // spacing is initially assumed to be EvenDblSpc, and that is changed to
80 // OddDblSpc depending on the lane number operand.
87 // Entries for NEON load/store information table. The table is sorted by
88 // PseudoOpc for fast binary-search lookups.
89 struct NEONLdStTableEntry
{
94 NEONRegSpacing RegSpacing
;
95 unsigned char NumRegs
; // D registers loaded or stored
96 unsigned char RegElts
; // elements per D register; used for lane ops
98 // Comparison methods for binary search of the table.
99 bool operator<(const NEONLdStTableEntry
&TE
) const {
100 return PseudoOpc
< TE
.PseudoOpc
;
102 friend bool operator<(const NEONLdStTableEntry
&TE
, unsigned PseudoOpc
) {
103 return TE
.PseudoOpc
< PseudoOpc
;
105 friend bool LLVM_ATTRIBUTE_UNUSED
operator<(unsigned PseudoOpc
,
106 const NEONLdStTableEntry
&TE
) {
107 return PseudoOpc
< TE
.PseudoOpc
;
112 static const NEONLdStTableEntry NEONLdStTable
[] = {
113 { ARM::VLD1LNq16Pseudo
, ARM::VLD1LNd16
, true, false, EvenDblSpc
, 1, 4 },
114 { ARM::VLD1LNq16Pseudo_UPD
, ARM::VLD1LNd16_UPD
, true, true, EvenDblSpc
, 1, 4 },
115 { ARM::VLD1LNq32Pseudo
, ARM::VLD1LNd32
, true, false, EvenDblSpc
, 1, 2 },
116 { ARM::VLD1LNq32Pseudo_UPD
, ARM::VLD1LNd32_UPD
, true, true, EvenDblSpc
, 1, 2 },
117 { ARM::VLD1LNq8Pseudo
, ARM::VLD1LNd8
, true, false, EvenDblSpc
, 1, 8 },
118 { ARM::VLD1LNq8Pseudo_UPD
, ARM::VLD1LNd8_UPD
, true, true, EvenDblSpc
, 1, 8 },
120 { ARM::VLD1d64QPseudo
, ARM::VLD1d64Q
, true, false, SingleSpc
, 4, 1 },
121 { ARM::VLD1d64QPseudo_UPD
, ARM::VLD1d64Q_UPD
, true, true, SingleSpc
, 4, 1 },
122 { ARM::VLD1d64TPseudo
, ARM::VLD1d64T
, true, false, SingleSpc
, 3, 1 },
123 { ARM::VLD1d64TPseudo_UPD
, ARM::VLD1d64T_UPD
, true, true, SingleSpc
, 3, 1 },
125 { ARM::VLD1q16Pseudo
, ARM::VLD1q16
, true, false, SingleSpc
, 2, 4 },
126 { ARM::VLD1q16Pseudo_UPD
, ARM::VLD1q16_UPD
, true, true, SingleSpc
, 2, 4 },
127 { ARM::VLD1q32Pseudo
, ARM::VLD1q32
, true, false, SingleSpc
, 2, 2 },
128 { ARM::VLD1q32Pseudo_UPD
, ARM::VLD1q32_UPD
, true, true, SingleSpc
, 2, 2 },
129 { ARM::VLD1q64Pseudo
, ARM::VLD1q64
, true, false, SingleSpc
, 2, 1 },
130 { ARM::VLD1q64Pseudo_UPD
, ARM::VLD1q64_UPD
, true, true, SingleSpc
, 2, 1 },
131 { ARM::VLD1q8Pseudo
, ARM::VLD1q8
, true, false, SingleSpc
, 2, 8 },
132 { ARM::VLD1q8Pseudo_UPD
, ARM::VLD1q8_UPD
, true, true, SingleSpc
, 2, 8 },
134 { ARM::VLD2LNd16Pseudo
, ARM::VLD2LNd16
, true, false, SingleSpc
, 2, 4 },
135 { ARM::VLD2LNd16Pseudo_UPD
, ARM::VLD2LNd16_UPD
, true, true, SingleSpc
, 2, 4 },
136 { ARM::VLD2LNd32Pseudo
, ARM::VLD2LNd32
, true, false, SingleSpc
, 2, 2 },
137 { ARM::VLD2LNd32Pseudo_UPD
, ARM::VLD2LNd32_UPD
, true, true, SingleSpc
, 2, 2 },
138 { ARM::VLD2LNd8Pseudo
, ARM::VLD2LNd8
, true, false, SingleSpc
, 2, 8 },
139 { ARM::VLD2LNd8Pseudo_UPD
, ARM::VLD2LNd8_UPD
, true, true, SingleSpc
, 2, 8 },
140 { ARM::VLD2LNq16Pseudo
, ARM::VLD2LNq16
, true, false, EvenDblSpc
, 2, 4 },
141 { ARM::VLD2LNq16Pseudo_UPD
, ARM::VLD2LNq16_UPD
, true, true, EvenDblSpc
, 2, 4 },
142 { ARM::VLD2LNq32Pseudo
, ARM::VLD2LNq32
, true, false, EvenDblSpc
, 2, 2 },
143 { ARM::VLD2LNq32Pseudo_UPD
, ARM::VLD2LNq32_UPD
, true, true, EvenDblSpc
, 2, 2 },
145 { ARM::VLD2d16Pseudo
, ARM::VLD2d16
, true, false, SingleSpc
, 2, 4 },
146 { ARM::VLD2d16Pseudo_UPD
, ARM::VLD2d16_UPD
, true, true, SingleSpc
, 2, 4 },
147 { ARM::VLD2d32Pseudo
, ARM::VLD2d32
, true, false, SingleSpc
, 2, 2 },
148 { ARM::VLD2d32Pseudo_UPD
, ARM::VLD2d32_UPD
, true, true, SingleSpc
, 2, 2 },
149 { ARM::VLD2d8Pseudo
, ARM::VLD2d8
, true, false, SingleSpc
, 2, 8 },
150 { ARM::VLD2d8Pseudo_UPD
, ARM::VLD2d8_UPD
, true, true, SingleSpc
, 2, 8 },
152 { ARM::VLD2q16Pseudo
, ARM::VLD2q16
, true, false, SingleSpc
, 4, 4 },
153 { ARM::VLD2q16Pseudo_UPD
, ARM::VLD2q16_UPD
, true, true, SingleSpc
, 4, 4 },
154 { ARM::VLD2q32Pseudo
, ARM::VLD2q32
, true, false, SingleSpc
, 4, 2 },
155 { ARM::VLD2q32Pseudo_UPD
, ARM::VLD2q32_UPD
, true, true, SingleSpc
, 4, 2 },
156 { ARM::VLD2q8Pseudo
, ARM::VLD2q8
, true, false, SingleSpc
, 4, 8 },
157 { ARM::VLD2q8Pseudo_UPD
, ARM::VLD2q8_UPD
, true, true, SingleSpc
, 4, 8 },
159 { ARM::VLD3LNd16Pseudo
, ARM::VLD3LNd16
, true, false, SingleSpc
, 3, 4 },
160 { ARM::VLD3LNd16Pseudo_UPD
, ARM::VLD3LNd16_UPD
, true, true, SingleSpc
, 3, 4 },
161 { ARM::VLD3LNd32Pseudo
, ARM::VLD3LNd32
, true, false, SingleSpc
, 3, 2 },
162 { ARM::VLD3LNd32Pseudo_UPD
, ARM::VLD3LNd32_UPD
, true, true, SingleSpc
, 3, 2 },
163 { ARM::VLD3LNd8Pseudo
, ARM::VLD3LNd8
, true, false, SingleSpc
, 3, 8 },
164 { ARM::VLD3LNd8Pseudo_UPD
, ARM::VLD3LNd8_UPD
, true, true, SingleSpc
, 3, 8 },
165 { ARM::VLD3LNq16Pseudo
, ARM::VLD3LNq16
, true, false, EvenDblSpc
, 3, 4 },
166 { ARM::VLD3LNq16Pseudo_UPD
, ARM::VLD3LNq16_UPD
, true, true, EvenDblSpc
, 3, 4 },
167 { ARM::VLD3LNq32Pseudo
, ARM::VLD3LNq32
, true, false, EvenDblSpc
, 3, 2 },
168 { ARM::VLD3LNq32Pseudo_UPD
, ARM::VLD3LNq32_UPD
, true, true, EvenDblSpc
, 3, 2 },
170 { ARM::VLD3d16Pseudo
, ARM::VLD3d16
, true, false, SingleSpc
, 3, 4 },
171 { ARM::VLD3d16Pseudo_UPD
, ARM::VLD3d16_UPD
, true, true, SingleSpc
, 3, 4 },
172 { ARM::VLD3d32Pseudo
, ARM::VLD3d32
, true, false, SingleSpc
, 3, 2 },
173 { ARM::VLD3d32Pseudo_UPD
, ARM::VLD3d32_UPD
, true, true, SingleSpc
, 3, 2 },
174 { ARM::VLD3d8Pseudo
, ARM::VLD3d8
, true, false, SingleSpc
, 3, 8 },
175 { ARM::VLD3d8Pseudo_UPD
, ARM::VLD3d8_UPD
, true, true, SingleSpc
, 3, 8 },
177 { ARM::VLD3q16Pseudo_UPD
, ARM::VLD3q16_UPD
, true, true, EvenDblSpc
, 3, 4 },
178 { ARM::VLD3q16oddPseudo_UPD
, ARM::VLD3q16_UPD
, true, true, OddDblSpc
, 3, 4 },
179 { ARM::VLD3q32Pseudo_UPD
, ARM::VLD3q32_UPD
, true, true, EvenDblSpc
, 3, 2 },
180 { ARM::VLD3q32oddPseudo_UPD
, ARM::VLD3q32_UPD
, true, true, OddDblSpc
, 3, 2 },
181 { ARM::VLD3q8Pseudo_UPD
, ARM::VLD3q8_UPD
, true, true, EvenDblSpc
, 3, 8 },
182 { ARM::VLD3q8oddPseudo_UPD
, ARM::VLD3q8_UPD
, true, true, OddDblSpc
, 3, 8 },
184 { ARM::VLD4LNd16Pseudo
, ARM::VLD4LNd16
, true, false, SingleSpc
, 4, 4 },
185 { ARM::VLD4LNd16Pseudo_UPD
, ARM::VLD4LNd16_UPD
, true, true, SingleSpc
, 4, 4 },
186 { ARM::VLD4LNd32Pseudo
, ARM::VLD4LNd32
, true, false, SingleSpc
, 4, 2 },
187 { ARM::VLD4LNd32Pseudo_UPD
, ARM::VLD4LNd32_UPD
, true, true, SingleSpc
, 4, 2 },
188 { ARM::VLD4LNd8Pseudo
, ARM::VLD4LNd8
, true, false, SingleSpc
, 4, 8 },
189 { ARM::VLD4LNd8Pseudo_UPD
, ARM::VLD4LNd8_UPD
, true, true, SingleSpc
, 4, 8 },
190 { ARM::VLD4LNq16Pseudo
, ARM::VLD4LNq16
, true, false, EvenDblSpc
, 4, 4 },
191 { ARM::VLD4LNq16Pseudo_UPD
, ARM::VLD4LNq16_UPD
, true, true, EvenDblSpc
, 4, 4 },
192 { ARM::VLD4LNq32Pseudo
, ARM::VLD4LNq32
, true, false, EvenDblSpc
, 4, 2 },
193 { ARM::VLD4LNq32Pseudo_UPD
, ARM::VLD4LNq32_UPD
, true, true, EvenDblSpc
, 4, 2 },
195 { ARM::VLD4d16Pseudo
, ARM::VLD4d16
, true, false, SingleSpc
, 4, 4 },
196 { ARM::VLD4d16Pseudo_UPD
, ARM::VLD4d16_UPD
, true, true, SingleSpc
, 4, 4 },
197 { ARM::VLD4d32Pseudo
, ARM::VLD4d32
, true, false, SingleSpc
, 4, 2 },
198 { ARM::VLD4d32Pseudo_UPD
, ARM::VLD4d32_UPD
, true, true, SingleSpc
, 4, 2 },
199 { ARM::VLD4d8Pseudo
, ARM::VLD4d8
, true, false, SingleSpc
, 4, 8 },
200 { ARM::VLD4d8Pseudo_UPD
, ARM::VLD4d8_UPD
, true, true, SingleSpc
, 4, 8 },
202 { ARM::VLD4q16Pseudo_UPD
, ARM::VLD4q16_UPD
, true, true, EvenDblSpc
, 4, 4 },
203 { ARM::VLD4q16oddPseudo_UPD
, ARM::VLD4q16_UPD
, true, true, OddDblSpc
, 4, 4 },
204 { ARM::VLD4q32Pseudo_UPD
, ARM::VLD4q32_UPD
, true, true, EvenDblSpc
, 4, 2 },
205 { ARM::VLD4q32oddPseudo_UPD
, ARM::VLD4q32_UPD
, true, true, OddDblSpc
, 4, 2 },
206 { ARM::VLD4q8Pseudo_UPD
, ARM::VLD4q8_UPD
, true, true, EvenDblSpc
, 4, 8 },
207 { ARM::VLD4q8oddPseudo_UPD
, ARM::VLD4q8_UPD
, true, true, OddDblSpc
, 4, 8 },
209 { ARM::VST1LNq16Pseudo
, ARM::VST1LNd16
, false, false, EvenDblSpc
, 1, 4 },
210 { ARM::VST1LNq16Pseudo_UPD
, ARM::VST1LNd16_UPD
,false, true, EvenDblSpc
, 1, 4 },
211 { ARM::VST1LNq32Pseudo
, ARM::VST1LNd32
, false, false, EvenDblSpc
, 1, 2 },
212 { ARM::VST1LNq32Pseudo_UPD
, ARM::VST1LNd32_UPD
,false, true, EvenDblSpc
, 1, 2 },
213 { ARM::VST1LNq8Pseudo
, ARM::VST1LNd8
, false, false, EvenDblSpc
, 1, 8 },
214 { ARM::VST1LNq8Pseudo_UPD
, ARM::VST1LNd8_UPD
, false, true, EvenDblSpc
, 1, 8 },
216 { ARM::VST1d64QPseudo
, ARM::VST1d64Q
, false, false, SingleSpc
, 4, 1 },
217 { ARM::VST1d64QPseudo_UPD
, ARM::VST1d64Q_UPD
, false, true, SingleSpc
, 4, 1 },
218 { ARM::VST1d64TPseudo
, ARM::VST1d64T
, false, false, SingleSpc
, 3, 1 },
219 { ARM::VST1d64TPseudo_UPD
, ARM::VST1d64T_UPD
, false, true, SingleSpc
, 3, 1 },
221 { ARM::VST1q16Pseudo
, ARM::VST1q16
, false, false, SingleSpc
, 2, 4 },
222 { ARM::VST1q16Pseudo_UPD
, ARM::VST1q16_UPD
, false, true, SingleSpc
, 2, 4 },
223 { ARM::VST1q32Pseudo
, ARM::VST1q32
, false, false, SingleSpc
, 2, 2 },
224 { ARM::VST1q32Pseudo_UPD
, ARM::VST1q32_UPD
, false, true, SingleSpc
, 2, 2 },
225 { ARM::VST1q64Pseudo
, ARM::VST1q64
, false, false, SingleSpc
, 2, 1 },
226 { ARM::VST1q64Pseudo_UPD
, ARM::VST1q64_UPD
, false, true, SingleSpc
, 2, 1 },
227 { ARM::VST1q8Pseudo
, ARM::VST1q8
, false, false, SingleSpc
, 2, 8 },
228 { ARM::VST1q8Pseudo_UPD
, ARM::VST1q8_UPD
, false, true, SingleSpc
, 2, 8 },
230 { ARM::VST2LNd16Pseudo
, ARM::VST2LNd16
, false, false, SingleSpc
, 2, 4 },
231 { ARM::VST2LNd16Pseudo_UPD
, ARM::VST2LNd16_UPD
, false, true, SingleSpc
, 2, 4 },
232 { ARM::VST2LNd32Pseudo
, ARM::VST2LNd32
, false, false, SingleSpc
, 2, 2 },
233 { ARM::VST2LNd32Pseudo_UPD
, ARM::VST2LNd32_UPD
, false, true, SingleSpc
, 2, 2 },
234 { ARM::VST2LNd8Pseudo
, ARM::VST2LNd8
, false, false, SingleSpc
, 2, 8 },
235 { ARM::VST2LNd8Pseudo_UPD
, ARM::VST2LNd8_UPD
, false, true, SingleSpc
, 2, 8 },
236 { ARM::VST2LNq16Pseudo
, ARM::VST2LNq16
, false, false, EvenDblSpc
, 2, 4},
237 { ARM::VST2LNq16Pseudo_UPD
, ARM::VST2LNq16_UPD
, false, true, EvenDblSpc
, 2, 4},
238 { ARM::VST2LNq32Pseudo
, ARM::VST2LNq32
, false, false, EvenDblSpc
, 2, 2},
239 { ARM::VST2LNq32Pseudo_UPD
, ARM::VST2LNq32_UPD
, false, true, EvenDblSpc
, 2, 2},
241 { ARM::VST2d16Pseudo
, ARM::VST2d16
, false, false, SingleSpc
, 2, 4 },
242 { ARM::VST2d16Pseudo_UPD
, ARM::VST2d16_UPD
, false, true, SingleSpc
, 2, 4 },
243 { ARM::VST2d32Pseudo
, ARM::VST2d32
, false, false, SingleSpc
, 2, 2 },
244 { ARM::VST2d32Pseudo_UPD
, ARM::VST2d32_UPD
, false, true, SingleSpc
, 2, 2 },
245 { ARM::VST2d8Pseudo
, ARM::VST2d8
, false, false, SingleSpc
, 2, 8 },
246 { ARM::VST2d8Pseudo_UPD
, ARM::VST2d8_UPD
, false, true, SingleSpc
, 2, 8 },
248 { ARM::VST2q16Pseudo
, ARM::VST2q16
, false, false, SingleSpc
, 4, 4 },
249 { ARM::VST2q16Pseudo_UPD
, ARM::VST2q16_UPD
, false, true, SingleSpc
, 4, 4 },
250 { ARM::VST2q32Pseudo
, ARM::VST2q32
, false, false, SingleSpc
, 4, 2 },
251 { ARM::VST2q32Pseudo_UPD
, ARM::VST2q32_UPD
, false, true, SingleSpc
, 4, 2 },
252 { ARM::VST2q8Pseudo
, ARM::VST2q8
, false, false, SingleSpc
, 4, 8 },
253 { ARM::VST2q8Pseudo_UPD
, ARM::VST2q8_UPD
, false, true, SingleSpc
, 4, 8 },
255 { ARM::VST3LNd16Pseudo
, ARM::VST3LNd16
, false, false, SingleSpc
, 3, 4 },
256 { ARM::VST3LNd16Pseudo_UPD
, ARM::VST3LNd16_UPD
, false, true, SingleSpc
, 3, 4 },
257 { ARM::VST3LNd32Pseudo
, ARM::VST3LNd32
, false, false, SingleSpc
, 3, 2 },
258 { ARM::VST3LNd32Pseudo_UPD
, ARM::VST3LNd32_UPD
, false, true, SingleSpc
, 3, 2 },
259 { ARM::VST3LNd8Pseudo
, ARM::VST3LNd8
, false, false, SingleSpc
, 3, 8 },
260 { ARM::VST3LNd8Pseudo_UPD
, ARM::VST3LNd8_UPD
, false, true, SingleSpc
, 3, 8 },
261 { ARM::VST3LNq16Pseudo
, ARM::VST3LNq16
, false, false, EvenDblSpc
, 3, 4},
262 { ARM::VST3LNq16Pseudo_UPD
, ARM::VST3LNq16_UPD
, false, true, EvenDblSpc
, 3, 4},
263 { ARM::VST3LNq32Pseudo
, ARM::VST3LNq32
, false, false, EvenDblSpc
, 3, 2},
264 { ARM::VST3LNq32Pseudo_UPD
, ARM::VST3LNq32_UPD
, false, true, EvenDblSpc
, 3, 2},
266 { ARM::VST3d16Pseudo
, ARM::VST3d16
, false, false, SingleSpc
, 3, 4 },
267 { ARM::VST3d16Pseudo_UPD
, ARM::VST3d16_UPD
, false, true, SingleSpc
, 3, 4 },
268 { ARM::VST3d32Pseudo
, ARM::VST3d32
, false, false, SingleSpc
, 3, 2 },
269 { ARM::VST3d32Pseudo_UPD
, ARM::VST3d32_UPD
, false, true, SingleSpc
, 3, 2 },
270 { ARM::VST3d8Pseudo
, ARM::VST3d8
, false, false, SingleSpc
, 3, 8 },
271 { ARM::VST3d8Pseudo_UPD
, ARM::VST3d8_UPD
, false, true, SingleSpc
, 3, 8 },
273 { ARM::VST3q16Pseudo_UPD
, ARM::VST3q16_UPD
, false, true, EvenDblSpc
, 3, 4 },
274 { ARM::VST3q16oddPseudo_UPD
, ARM::VST3q16_UPD
, false, true, OddDblSpc
, 3, 4 },
275 { ARM::VST3q32Pseudo_UPD
, ARM::VST3q32_UPD
, false, true, EvenDblSpc
, 3, 2 },
276 { ARM::VST3q32oddPseudo_UPD
, ARM::VST3q32_UPD
, false, true, OddDblSpc
, 3, 2 },
277 { ARM::VST3q8Pseudo_UPD
, ARM::VST3q8_UPD
, false, true, EvenDblSpc
, 3, 8 },
278 { ARM::VST3q8oddPseudo_UPD
, ARM::VST3q8_UPD
, false, true, OddDblSpc
, 3, 8 },
280 { ARM::VST4LNd16Pseudo
, ARM::VST4LNd16
, false, false, SingleSpc
, 4, 4 },
281 { ARM::VST4LNd16Pseudo_UPD
, ARM::VST4LNd16_UPD
, false, true, SingleSpc
, 4, 4 },
282 { ARM::VST4LNd32Pseudo
, ARM::VST4LNd32
, false, false, SingleSpc
, 4, 2 },
283 { ARM::VST4LNd32Pseudo_UPD
, ARM::VST4LNd32_UPD
, false, true, SingleSpc
, 4, 2 },
284 { ARM::VST4LNd8Pseudo
, ARM::VST4LNd8
, false, false, SingleSpc
, 4, 8 },
285 { ARM::VST4LNd8Pseudo_UPD
, ARM::VST4LNd8_UPD
, false, true, SingleSpc
, 4, 8 },
286 { ARM::VST4LNq16Pseudo
, ARM::VST4LNq16
, false, false, EvenDblSpc
, 4, 4},
287 { ARM::VST4LNq16Pseudo_UPD
, ARM::VST4LNq16_UPD
, false, true, EvenDblSpc
, 4, 4},
288 { ARM::VST4LNq32Pseudo
, ARM::VST4LNq32
, false, false, EvenDblSpc
, 4, 2},
289 { ARM::VST4LNq32Pseudo_UPD
, ARM::VST4LNq32_UPD
, false, true, EvenDblSpc
, 4, 2},
291 { ARM::VST4d16Pseudo
, ARM::VST4d16
, false, false, SingleSpc
, 4, 4 },
292 { ARM::VST4d16Pseudo_UPD
, ARM::VST4d16_UPD
, false, true, SingleSpc
, 4, 4 },
293 { ARM::VST4d32Pseudo
, ARM::VST4d32
, false, false, SingleSpc
, 4, 2 },
294 { ARM::VST4d32Pseudo_UPD
, ARM::VST4d32_UPD
, false, true, SingleSpc
, 4, 2 },
295 { ARM::VST4d8Pseudo
, ARM::VST4d8
, false, false, SingleSpc
, 4, 8 },
296 { ARM::VST4d8Pseudo_UPD
, ARM::VST4d8_UPD
, false, true, SingleSpc
, 4, 8 },
298 { ARM::VST4q16Pseudo_UPD
, ARM::VST4q16_UPD
, false, true, EvenDblSpc
, 4, 4 },
299 { ARM::VST4q16oddPseudo_UPD
, ARM::VST4q16_UPD
, false, true, OddDblSpc
, 4, 4 },
300 { ARM::VST4q32Pseudo_UPD
, ARM::VST4q32_UPD
, false, true, EvenDblSpc
, 4, 2 },
301 { ARM::VST4q32oddPseudo_UPD
, ARM::VST4q32_UPD
, false, true, OddDblSpc
, 4, 2 },
302 { ARM::VST4q8Pseudo_UPD
, ARM::VST4q8_UPD
, false, true, EvenDblSpc
, 4, 8 },
303 { ARM::VST4q8oddPseudo_UPD
, ARM::VST4q8_UPD
, false, true, OddDblSpc
, 4, 8 }
306 /// LookupNEONLdSt - Search the NEONLdStTable for information about a NEON
307 /// load or store pseudo instruction.
308 static const NEONLdStTableEntry
*LookupNEONLdSt(unsigned Opcode
) {
309 unsigned NumEntries
= array_lengthof(NEONLdStTable
);
312 // Make sure the table is sorted.
313 static bool TableChecked
= false;
315 for (unsigned i
= 0; i
!= NumEntries
-1; ++i
)
316 assert(NEONLdStTable
[i
] < NEONLdStTable
[i
+1] &&
317 "NEONLdStTable is not sorted!");
322 const NEONLdStTableEntry
*I
=
323 std::lower_bound(NEONLdStTable
, NEONLdStTable
+ NumEntries
, Opcode
);
324 if (I
!= NEONLdStTable
+ NumEntries
&& I
->PseudoOpc
== Opcode
)
329 /// GetDSubRegs - Get 4 D subregisters of a Q, QQ, or QQQQ register,
330 /// corresponding to the specified register spacing. Not all of the results
331 /// are necessarily valid, e.g., a Q register only has 2 D subregisters.
332 static void GetDSubRegs(unsigned Reg
, NEONRegSpacing RegSpc
,
333 const TargetRegisterInfo
*TRI
, unsigned &D0
,
334 unsigned &D1
, unsigned &D2
, unsigned &D3
) {
335 if (RegSpc
== SingleSpc
) {
336 D0
= TRI
->getSubReg(Reg
, ARM::dsub_0
);
337 D1
= TRI
->getSubReg(Reg
, ARM::dsub_1
);
338 D2
= TRI
->getSubReg(Reg
, ARM::dsub_2
);
339 D3
= TRI
->getSubReg(Reg
, ARM::dsub_3
);
340 } else if (RegSpc
== EvenDblSpc
) {
341 D0
= TRI
->getSubReg(Reg
, ARM::dsub_0
);
342 D1
= TRI
->getSubReg(Reg
, ARM::dsub_2
);
343 D2
= TRI
->getSubReg(Reg
, ARM::dsub_4
);
344 D3
= TRI
->getSubReg(Reg
, ARM::dsub_6
);
346 assert(RegSpc
== OddDblSpc
&& "unknown register spacing");
347 D0
= TRI
->getSubReg(Reg
, ARM::dsub_1
);
348 D1
= TRI
->getSubReg(Reg
, ARM::dsub_3
);
349 D2
= TRI
->getSubReg(Reg
, ARM::dsub_5
);
350 D3
= TRI
->getSubReg(Reg
, ARM::dsub_7
);
354 /// ExpandVLD - Translate VLD pseudo instructions with Q, QQ or QQQQ register
355 /// operands to real VLD instructions with D register operands.
356 void ARMExpandPseudo::ExpandVLD(MachineBasicBlock::iterator
&MBBI
) {
357 MachineInstr
&MI
= *MBBI
;
358 MachineBasicBlock
&MBB
= *MI
.getParent();
360 const NEONLdStTableEntry
*TableEntry
= LookupNEONLdSt(MI
.getOpcode());
361 assert(TableEntry
&& TableEntry
->IsLoad
&& "NEONLdStTable lookup failed");
362 NEONRegSpacing RegSpc
= TableEntry
->RegSpacing
;
363 unsigned NumRegs
= TableEntry
->NumRegs
;
365 MachineInstrBuilder MIB
= BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
366 TII
->get(TableEntry
->RealOpc
));
369 bool DstIsDead
= MI
.getOperand(OpIdx
).isDead();
370 unsigned DstReg
= MI
.getOperand(OpIdx
++).getReg();
371 unsigned D0
, D1
, D2
, D3
;
372 GetDSubRegs(DstReg
, RegSpc
, TRI
, D0
, D1
, D2
, D3
);
373 MIB
.addReg(D0
, RegState::Define
| getDeadRegState(DstIsDead
))
374 .addReg(D1
, RegState::Define
| getDeadRegState(DstIsDead
));
376 MIB
.addReg(D2
, RegState::Define
| getDeadRegState(DstIsDead
));
378 MIB
.addReg(D3
, RegState::Define
| getDeadRegState(DstIsDead
));
380 if (TableEntry
->HasWriteBack
)
381 MIB
.addOperand(MI
.getOperand(OpIdx
++));
383 // Copy the addrmode6 operands.
384 MIB
.addOperand(MI
.getOperand(OpIdx
++));
385 MIB
.addOperand(MI
.getOperand(OpIdx
++));
386 // Copy the am6offset operand.
387 if (TableEntry
->HasWriteBack
)
388 MIB
.addOperand(MI
.getOperand(OpIdx
++));
390 // For an instruction writing double-spaced subregs, the pseudo instruction
391 // has an extra operand that is a use of the super-register. Record the
392 // operand index and skip over it.
393 unsigned SrcOpIdx
= 0;
394 if (RegSpc
== EvenDblSpc
|| RegSpc
== OddDblSpc
)
397 // Copy the predicate operands.
398 MIB
.addOperand(MI
.getOperand(OpIdx
++));
399 MIB
.addOperand(MI
.getOperand(OpIdx
++));
401 // Copy the super-register source operand used for double-spaced subregs over
402 // to the new instruction as an implicit operand.
404 MachineOperand MO
= MI
.getOperand(SrcOpIdx
);
405 MO
.setImplicit(true);
408 // Add an implicit def for the super-register.
409 MIB
.addReg(DstReg
, RegState::ImplicitDefine
| getDeadRegState(DstIsDead
));
410 TransferImpOps(MI
, MIB
, MIB
);
411 MI
.eraseFromParent();
414 /// ExpandVST - Translate VST pseudo instructions with Q, QQ or QQQQ register
415 /// operands to real VST instructions with D register operands.
416 void ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator
&MBBI
) {
417 MachineInstr
&MI
= *MBBI
;
418 MachineBasicBlock
&MBB
= *MI
.getParent();
420 const NEONLdStTableEntry
*TableEntry
= LookupNEONLdSt(MI
.getOpcode());
421 assert(TableEntry
&& !TableEntry
->IsLoad
&& "NEONLdStTable lookup failed");
422 NEONRegSpacing RegSpc
= TableEntry
->RegSpacing
;
423 unsigned NumRegs
= TableEntry
->NumRegs
;
425 MachineInstrBuilder MIB
= BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
426 TII
->get(TableEntry
->RealOpc
));
428 if (TableEntry
->HasWriteBack
)
429 MIB
.addOperand(MI
.getOperand(OpIdx
++));
431 // Copy the addrmode6 operands.
432 MIB
.addOperand(MI
.getOperand(OpIdx
++));
433 MIB
.addOperand(MI
.getOperand(OpIdx
++));
434 // Copy the am6offset operand.
435 if (TableEntry
->HasWriteBack
)
436 MIB
.addOperand(MI
.getOperand(OpIdx
++));
438 bool SrcIsKill
= MI
.getOperand(OpIdx
).isKill();
439 unsigned SrcReg
= MI
.getOperand(OpIdx
++).getReg();
440 unsigned D0
, D1
, D2
, D3
;
441 GetDSubRegs(SrcReg
, RegSpc
, TRI
, D0
, D1
, D2
, D3
);
442 MIB
.addReg(D0
).addReg(D1
);
448 // Copy the predicate operands.
449 MIB
.addOperand(MI
.getOperand(OpIdx
++));
450 MIB
.addOperand(MI
.getOperand(OpIdx
++));
453 // Add an implicit kill for the super-reg.
454 (*MIB
).addRegisterKilled(SrcReg
, TRI
, true);
455 TransferImpOps(MI
, MIB
, MIB
);
456 MI
.eraseFromParent();
459 /// ExpandLaneOp - Translate VLD*LN and VST*LN instructions with Q, QQ or QQQQ
460 /// register operands to real instructions with D register operands.
461 void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator
&MBBI
) {
462 MachineInstr
&MI
= *MBBI
;
463 MachineBasicBlock
&MBB
= *MI
.getParent();
465 const NEONLdStTableEntry
*TableEntry
= LookupNEONLdSt(MI
.getOpcode());
466 assert(TableEntry
&& "NEONLdStTable lookup failed");
467 NEONRegSpacing RegSpc
= TableEntry
->RegSpacing
;
468 unsigned NumRegs
= TableEntry
->NumRegs
;
469 unsigned RegElts
= TableEntry
->RegElts
;
471 MachineInstrBuilder MIB
= BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
472 TII
->get(TableEntry
->RealOpc
));
474 // The lane operand is always the 3rd from last operand, before the 2
475 // predicate operands.
476 unsigned Lane
= MI
.getOperand(MI
.getDesc().getNumOperands() - 3).getImm();
478 // Adjust the lane and spacing as needed for Q registers.
479 assert(RegSpc
!= OddDblSpc
&& "unexpected register spacing for VLD/VST-lane");
480 if (RegSpc
== EvenDblSpc
&& Lane
>= RegElts
) {
484 assert(Lane
< RegElts
&& "out of range lane for VLD/VST-lane");
486 unsigned D0
, D1
, D2
, D3
;
488 bool DstIsDead
= false;
489 if (TableEntry
->IsLoad
) {
490 DstIsDead
= MI
.getOperand(OpIdx
).isDead();
491 DstReg
= MI
.getOperand(OpIdx
++).getReg();
492 GetDSubRegs(DstReg
, RegSpc
, TRI
, D0
, D1
, D2
, D3
);
493 MIB
.addReg(D0
, RegState::Define
| getDeadRegState(DstIsDead
));
495 MIB
.addReg(D1
, RegState::Define
| getDeadRegState(DstIsDead
));
497 MIB
.addReg(D2
, RegState::Define
| getDeadRegState(DstIsDead
));
499 MIB
.addReg(D3
, RegState::Define
| getDeadRegState(DstIsDead
));
502 if (TableEntry
->HasWriteBack
)
503 MIB
.addOperand(MI
.getOperand(OpIdx
++));
505 // Copy the addrmode6 operands.
506 MIB
.addOperand(MI
.getOperand(OpIdx
++));
507 MIB
.addOperand(MI
.getOperand(OpIdx
++));
508 // Copy the am6offset operand.
509 if (TableEntry
->HasWriteBack
)
510 MIB
.addOperand(MI
.getOperand(OpIdx
++));
512 // Grab the super-register source.
513 MachineOperand MO
= MI
.getOperand(OpIdx
++);
514 if (!TableEntry
->IsLoad
)
515 GetDSubRegs(MO
.getReg(), RegSpc
, TRI
, D0
, D1
, D2
, D3
);
517 // Add the subregs as sources of the new instruction.
518 unsigned SrcFlags
= (getUndefRegState(MO
.isUndef()) |
519 getKillRegState(MO
.isKill()));
520 MIB
.addReg(D0
, SrcFlags
);
522 MIB
.addReg(D1
, SrcFlags
);
524 MIB
.addReg(D2
, SrcFlags
);
526 MIB
.addReg(D3
, SrcFlags
);
528 // Add the lane number operand.
532 // Copy the predicate operands.
533 MIB
.addOperand(MI
.getOperand(OpIdx
++));
534 MIB
.addOperand(MI
.getOperand(OpIdx
++));
536 // Copy the super-register source to be an implicit source.
537 MO
.setImplicit(true);
539 if (TableEntry
->IsLoad
)
540 // Add an implicit def for the super-register.
541 MIB
.addReg(DstReg
, RegState::ImplicitDefine
| getDeadRegState(DstIsDead
));
542 TransferImpOps(MI
, MIB
, MIB
);
543 MI
.eraseFromParent();
546 /// ExpandVTBL - Translate VTBL and VTBX pseudo instructions with Q or QQ
547 /// register operands to real instructions with D register operands.
548 void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator
&MBBI
,
549 unsigned Opc
, bool IsExt
, unsigned NumRegs
) {
550 MachineInstr
&MI
= *MBBI
;
551 MachineBasicBlock
&MBB
= *MI
.getParent();
553 MachineInstrBuilder MIB
= BuildMI(MBB
, MBBI
, MI
.getDebugLoc(), TII
->get(Opc
));
556 // Transfer the destination register operand.
557 MIB
.addOperand(MI
.getOperand(OpIdx
++));
559 MIB
.addOperand(MI
.getOperand(OpIdx
++));
561 bool SrcIsKill
= MI
.getOperand(OpIdx
).isKill();
562 unsigned SrcReg
= MI
.getOperand(OpIdx
++).getReg();
563 unsigned D0
, D1
, D2
, D3
;
564 GetDSubRegs(SrcReg
, SingleSpc
, TRI
, D0
, D1
, D2
, D3
);
565 MIB
.addReg(D0
).addReg(D1
);
571 // Copy the other source register operand.
572 MIB
.addOperand(MI
.getOperand(OpIdx
++));
574 // Copy the predicate operands.
575 MIB
.addOperand(MI
.getOperand(OpIdx
++));
576 MIB
.addOperand(MI
.getOperand(OpIdx
++));
579 // Add an implicit kill for the super-reg.
580 (*MIB
).addRegisterKilled(SrcReg
, TRI
, true);
581 TransferImpOps(MI
, MIB
, MIB
);
582 MI
.eraseFromParent();
585 bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock
&MBB
) {
586 bool Modified
= false;
588 MachineBasicBlock::iterator MBBI
= MBB
.begin(), E
= MBB
.end();
590 MachineInstr
&MI
= *MBBI
;
591 MachineBasicBlock::iterator NMBBI
= llvm::next(MBBI
);
593 bool ModifiedOp
= true;
594 unsigned Opcode
= MI
.getOpcode();
600 case ARM::Int_eh_sjlj_dispatchsetup
: {
601 MachineFunction
&MF
= *MI
.getParent()->getParent();
602 const ARMBaseInstrInfo
*AII
=
603 static_cast<const ARMBaseInstrInfo
*>(TII
);
604 const ARMBaseRegisterInfo
&RI
= AII
->getRegisterInfo();
605 // For functions using a base pointer, we rematerialize it (via the frame
606 // pointer) here since eh.sjlj.setjmp and eh.sjlj.longjmp don't do it
607 // for us. Otherwise, expand to nothing.
608 if (RI
.hasBasePointer(MF
)) {
609 ARMFunctionInfo
*AFI
= MF
.getInfo
<ARMFunctionInfo
>();
610 int32_t NumBytes
= AFI
->getFramePtrSpillOffset();
611 unsigned FramePtr
= RI
.getFrameRegister(MF
);
612 assert (RI
.hasFP(MF
) && "base pointer without frame pointer?");
614 if (AFI
->isThumb2Function()) {
615 llvm::emitT2RegPlusImmediate(MBB
, MBBI
, MI
.getDebugLoc(), ARM::R6
,
616 FramePtr
, -NumBytes
, ARMCC::AL
, 0, *TII
);
617 } else if (AFI
->isThumbFunction()) {
618 llvm::emitThumbRegPlusImmediate(MBB
, MBBI
, ARM::R6
,
620 *TII
, RI
, MI
.getDebugLoc());
622 llvm::emitARMRegPlusImmediate(MBB
, MBBI
, MI
.getDebugLoc(), ARM::R6
,
623 FramePtr
, -NumBytes
, ARMCC::AL
, 0,
626 // If there's dynamic realignment, adjust for it.
627 if (RI
.needsStackRealignment(MF
)) {
628 MachineFrameInfo
*MFI
= MF
.getFrameInfo();
629 unsigned MaxAlign
= MFI
->getMaxAlignment();
630 assert (!AFI
->isThumb1OnlyFunction());
631 // Emit bic r6, r6, MaxAlign
632 unsigned bicOpc
= AFI
->isThumbFunction() ?
633 ARM::t2BICri
: ARM::BICri
;
634 AddDefaultCC(AddDefaultPred(BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
635 TII
->get(bicOpc
), ARM::R6
)
636 .addReg(ARM::R6
, RegState::Kill
)
637 .addImm(MaxAlign
-1)));
641 MI
.eraseFromParent();
645 case ARM::MOVsrl_flag
:
646 case ARM::MOVsra_flag
: {
647 // These are just fancy MOVs insructions.
648 AddDefaultPred(BuildMI(MBB
, MBBI
, MI
.getDebugLoc(), TII
->get(ARM::MOVs
),
649 MI
.getOperand(0).getReg())
650 .addOperand(MI
.getOperand(1))
652 .addImm(ARM_AM::getSORegOpc((Opcode
== ARM::MOVsrl_flag
? ARM_AM::lsr
654 .addReg(ARM::CPSR
, RegState::Define
);
655 MI
.eraseFromParent();
659 // This encodes as "MOVs Rd, Rm, rrx
660 MachineInstrBuilder MIB
=
661 AddDefaultPred(BuildMI(MBB
, MBBI
, MI
.getDebugLoc(), TII
->get(ARM::MOVs
),
662 MI
.getOperand(0).getReg())
663 .addOperand(MI
.getOperand(1))
664 .addOperand(MI
.getOperand(1))
665 .addImm(ARM_AM::getSORegOpc(ARM_AM::rrx
, 0)))
667 TransferImpOps(MI
, MIB
, MIB
);
668 MI
.eraseFromParent();
671 case ARM::tLDRpci_pic
:
672 case ARM::t2LDRpci_pic
: {
673 unsigned NewLdOpc
= (Opcode
== ARM::tLDRpci_pic
)
674 ? ARM::tLDRpci
: ARM::t2LDRpci
;
675 unsigned DstReg
= MI
.getOperand(0).getReg();
676 bool DstIsDead
= MI
.getOperand(0).isDead();
677 MachineInstrBuilder MIB1
=
678 AddDefaultPred(BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
679 TII
->get(NewLdOpc
), DstReg
)
680 .addOperand(MI
.getOperand(1)));
681 (*MIB1
).setMemRefs(MI
.memoperands_begin(), MI
.memoperands_end());
682 MachineInstrBuilder MIB2
= BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
683 TII
->get(ARM::tPICADD
))
684 .addReg(DstReg
, RegState::Define
| getDeadRegState(DstIsDead
))
686 .addOperand(MI
.getOperand(2));
687 TransferImpOps(MI
, MIB1
, MIB2
);
688 MI
.eraseFromParent();
693 case ARM::t2MOVi32imm
: {
694 unsigned PredReg
= 0;
695 ARMCC::CondCodes Pred
= llvm::getInstrPredicate(&MI
, PredReg
);
696 unsigned DstReg
= MI
.getOperand(0).getReg();
697 bool DstIsDead
= MI
.getOperand(0).isDead();
698 const MachineOperand
&MO
= MI
.getOperand(1);
699 MachineInstrBuilder LO16
, HI16
;
701 LO16
= BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
702 TII
->get(Opcode
== ARM::MOVi32imm
?
703 ARM::MOVi16
: ARM::t2MOVi16
),
705 HI16
= BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
706 TII
->get(Opcode
== ARM::MOVi32imm
?
707 ARM::MOVTi16
: ARM::t2MOVTi16
))
708 .addReg(DstReg
, RegState::Define
| getDeadRegState(DstIsDead
))
712 unsigned Imm
= MO
.getImm();
713 unsigned Lo16
= Imm
& 0xffff;
714 unsigned Hi16
= (Imm
>> 16) & 0xffff;
715 LO16
= LO16
.addImm(Lo16
);
716 HI16
= HI16
.addImm(Hi16
);
718 const GlobalValue
*GV
= MO
.getGlobal();
719 unsigned TF
= MO
.getTargetFlags();
720 LO16
= LO16
.addGlobalAddress(GV
, MO
.getOffset(), TF
| ARMII::MO_LO16
);
721 HI16
= HI16
.addGlobalAddress(GV
, MO
.getOffset(), TF
| ARMII::MO_HI16
);
723 (*LO16
).setMemRefs(MI
.memoperands_begin(), MI
.memoperands_end());
724 (*HI16
).setMemRefs(MI
.memoperands_begin(), MI
.memoperands_end());
725 LO16
.addImm(Pred
).addReg(PredReg
);
726 HI16
.addImm(Pred
).addReg(PredReg
);
727 TransferImpOps(MI
, LO16
, HI16
);
728 MI
.eraseFromParent();
732 case ARM::MOVi2pieces
: {
733 unsigned PredReg
= 0;
734 ARMCC::CondCodes Pred
= llvm::getInstrPredicate(&MI
, PredReg
);
735 unsigned DstReg
= MI
.getOperand(0).getReg();
736 bool DstIsDead
= MI
.getOperand(0).isDead();
737 const MachineOperand
&MO
= MI
.getOperand(1);
738 MachineInstrBuilder LO16
, HI16
;
740 LO16
= BuildMI(MBB
, MBBI
, MI
.getDebugLoc(), TII
->get(ARM::MOVi
), DstReg
);
741 HI16
= BuildMI(MBB
, MBBI
, MI
.getDebugLoc(), TII
->get(ARM::ORRri
))
742 .addReg(DstReg
, RegState::Define
| getDeadRegState(DstIsDead
))
745 assert (MO
.isImm() && "MOVi2pieces w/ non-immediate source operand!");
746 unsigned ImmVal
= (unsigned)MO
.getImm();
747 unsigned SOImmValV1
= ARM_AM::getSOImmTwoPartFirst(ImmVal
);
748 unsigned SOImmValV2
= ARM_AM::getSOImmTwoPartSecond(ImmVal
);
749 LO16
= LO16
.addImm(SOImmValV1
);
750 HI16
= HI16
.addImm(SOImmValV2
);
751 (*LO16
).setMemRefs(MI
.memoperands_begin(), MI
.memoperands_end());
752 (*HI16
).setMemRefs(MI
.memoperands_begin(), MI
.memoperands_end());
753 LO16
.addImm(Pred
).addReg(PredReg
).addReg(0);
754 HI16
.addImm(Pred
).addReg(PredReg
).addReg(0);
755 TransferImpOps(MI
, LO16
, HI16
);
756 MI
.eraseFromParent();
761 unsigned DstReg
= MI
.getOperand(0).getReg();
762 bool DstIsDead
= MI
.getOperand(0).isDead();
763 unsigned EvenDst
= TRI
->getSubReg(DstReg
, ARM::qsub_0
);
764 unsigned OddDst
= TRI
->getSubReg(DstReg
, ARM::qsub_1
);
765 unsigned SrcReg
= MI
.getOperand(1).getReg();
766 bool SrcIsKill
= MI
.getOperand(1).isKill();
767 unsigned EvenSrc
= TRI
->getSubReg(SrcReg
, ARM::qsub_0
);
768 unsigned OddSrc
= TRI
->getSubReg(SrcReg
, ARM::qsub_1
);
769 MachineInstrBuilder Even
=
770 AddDefaultPred(BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
771 TII
->get(ARM::VMOVQ
))
773 RegState::Define
| getDeadRegState(DstIsDead
))
774 .addReg(EvenSrc
, getKillRegState(SrcIsKill
)));
775 MachineInstrBuilder Odd
=
776 AddDefaultPred(BuildMI(MBB
, MBBI
, MI
.getDebugLoc(),
777 TII
->get(ARM::VMOVQ
))
779 RegState::Define
| getDeadRegState(DstIsDead
))
780 .addReg(OddSrc
, getKillRegState(SrcIsKill
)));
781 TransferImpOps(MI
, Even
, Odd
);
782 MI
.eraseFromParent();
787 MachineInstrBuilder MIB
=
788 BuildMI(MBB
, MBBI
, MI
.getDebugLoc(), TII
->get(ARM::VLDMD
));
790 // Grab the Q register destination.
791 bool DstIsDead
= MI
.getOperand(OpIdx
).isDead();
792 unsigned DstReg
= MI
.getOperand(OpIdx
++).getReg();
793 // Copy the addrmode4 operands.
794 MIB
.addOperand(MI
.getOperand(OpIdx
++));
795 MIB
.addOperand(MI
.getOperand(OpIdx
++));
796 // Copy the predicate operands.
797 MIB
.addOperand(MI
.getOperand(OpIdx
++));
798 MIB
.addOperand(MI
.getOperand(OpIdx
++));
799 // Add the destination operands (D subregs).
800 unsigned D0
= TRI
->getSubReg(DstReg
, ARM::dsub_0
);
801 unsigned D1
= TRI
->getSubReg(DstReg
, ARM::dsub_1
);
802 MIB
.addReg(D0
, RegState::Define
| getDeadRegState(DstIsDead
))
803 .addReg(D1
, RegState::Define
| getDeadRegState(DstIsDead
));
804 // Add an implicit def for the super-register.
805 MIB
.addReg(DstReg
, RegState::ImplicitDefine
| getDeadRegState(DstIsDead
));
806 TransferImpOps(MI
, MIB
, MIB
);
807 MI
.eraseFromParent();
812 MachineInstrBuilder MIB
=
813 BuildMI(MBB
, MBBI
, MI
.getDebugLoc(), TII
->get(ARM::VSTMD
));
815 // Grab the Q register source.
816 bool SrcIsKill
= MI
.getOperand(OpIdx
).isKill();
817 unsigned SrcReg
= MI
.getOperand(OpIdx
++).getReg();
818 // Copy the addrmode4 operands.
819 MIB
.addOperand(MI
.getOperand(OpIdx
++));
820 MIB
.addOperand(MI
.getOperand(OpIdx
++));
821 // Copy the predicate operands.
822 MIB
.addOperand(MI
.getOperand(OpIdx
++));
823 MIB
.addOperand(MI
.getOperand(OpIdx
++));
824 // Add the source operands (D subregs).
825 unsigned D0
= TRI
->getSubReg(SrcReg
, ARM::dsub_0
);
826 unsigned D1
= TRI
->getSubReg(SrcReg
, ARM::dsub_1
);
827 MIB
.addReg(D0
).addReg(D1
);
829 // Add an implicit kill for the Q register.
830 (*MIB
).addRegisterKilled(SrcReg
, TRI
, true);
831 TransferImpOps(MI
, MIB
, MIB
);
832 MI
.eraseFromParent();
837 unsigned NewOpc
= Opcode
== ARM::VDUPfqf
? ARM::VDUPLNfq
: ARM::VDUPLNfd
;
838 MachineInstrBuilder MIB
=
839 BuildMI(MBB
, MBBI
, MI
.getDebugLoc(), TII
->get(NewOpc
));
841 unsigned SrcReg
= MI
.getOperand(1).getReg();
842 unsigned Lane
= getARMRegisterNumbering(SrcReg
) & 1;
843 unsigned DReg
= TRI
->getMatchingSuperReg(SrcReg
,
844 Lane
& 1 ? ARM::ssub_1
: ARM::ssub_0
, &ARM::DPR_VFP2RegClass
);
845 // The lane is [0,1] for the containing DReg superregister.
846 // Copy the dst/src register operands.
847 MIB
.addOperand(MI
.getOperand(OpIdx
++));
850 // Add the lane select operand.
852 // Add the predicate operands.
853 MIB
.addOperand(MI
.getOperand(OpIdx
++));
854 MIB
.addOperand(MI
.getOperand(OpIdx
++));
856 TransferImpOps(MI
, MIB
, MIB
);
857 MI
.eraseFromParent();
861 case ARM::VLD1q8Pseudo
:
862 case ARM::VLD1q16Pseudo
:
863 case ARM::VLD1q32Pseudo
:
864 case ARM::VLD1q64Pseudo
:
865 case ARM::VLD1q8Pseudo_UPD
:
866 case ARM::VLD1q16Pseudo_UPD
:
867 case ARM::VLD1q32Pseudo_UPD
:
868 case ARM::VLD1q64Pseudo_UPD
:
869 case ARM::VLD2d8Pseudo
:
870 case ARM::VLD2d16Pseudo
:
871 case ARM::VLD2d32Pseudo
:
872 case ARM::VLD2q8Pseudo
:
873 case ARM::VLD2q16Pseudo
:
874 case ARM::VLD2q32Pseudo
:
875 case ARM::VLD2d8Pseudo_UPD
:
876 case ARM::VLD2d16Pseudo_UPD
:
877 case ARM::VLD2d32Pseudo_UPD
:
878 case ARM::VLD2q8Pseudo_UPD
:
879 case ARM::VLD2q16Pseudo_UPD
:
880 case ARM::VLD2q32Pseudo_UPD
:
881 case ARM::VLD3d8Pseudo
:
882 case ARM::VLD3d16Pseudo
:
883 case ARM::VLD3d32Pseudo
:
884 case ARM::VLD1d64TPseudo
:
885 case ARM::VLD3d8Pseudo_UPD
:
886 case ARM::VLD3d16Pseudo_UPD
:
887 case ARM::VLD3d32Pseudo_UPD
:
888 case ARM::VLD1d64TPseudo_UPD
:
889 case ARM::VLD3q8Pseudo_UPD
:
890 case ARM::VLD3q16Pseudo_UPD
:
891 case ARM::VLD3q32Pseudo_UPD
:
892 case ARM::VLD3q8oddPseudo_UPD
:
893 case ARM::VLD3q16oddPseudo_UPD
:
894 case ARM::VLD3q32oddPseudo_UPD
:
895 case ARM::VLD4d8Pseudo
:
896 case ARM::VLD4d16Pseudo
:
897 case ARM::VLD4d32Pseudo
:
898 case ARM::VLD1d64QPseudo
:
899 case ARM::VLD4d8Pseudo_UPD
:
900 case ARM::VLD4d16Pseudo_UPD
:
901 case ARM::VLD4d32Pseudo_UPD
:
902 case ARM::VLD1d64QPseudo_UPD
:
903 case ARM::VLD4q8Pseudo_UPD
:
904 case ARM::VLD4q16Pseudo_UPD
:
905 case ARM::VLD4q32Pseudo_UPD
:
906 case ARM::VLD4q8oddPseudo_UPD
:
907 case ARM::VLD4q16oddPseudo_UPD
:
908 case ARM::VLD4q32oddPseudo_UPD
:
912 case ARM::VST1q8Pseudo
:
913 case ARM::VST1q16Pseudo
:
914 case ARM::VST1q32Pseudo
:
915 case ARM::VST1q64Pseudo
:
916 case ARM::VST1q8Pseudo_UPD
:
917 case ARM::VST1q16Pseudo_UPD
:
918 case ARM::VST1q32Pseudo_UPD
:
919 case ARM::VST1q64Pseudo_UPD
:
920 case ARM::VST2d8Pseudo
:
921 case ARM::VST2d16Pseudo
:
922 case ARM::VST2d32Pseudo
:
923 case ARM::VST2q8Pseudo
:
924 case ARM::VST2q16Pseudo
:
925 case ARM::VST2q32Pseudo
:
926 case ARM::VST2d8Pseudo_UPD
:
927 case ARM::VST2d16Pseudo_UPD
:
928 case ARM::VST2d32Pseudo_UPD
:
929 case ARM::VST2q8Pseudo_UPD
:
930 case ARM::VST2q16Pseudo_UPD
:
931 case ARM::VST2q32Pseudo_UPD
:
932 case ARM::VST3d8Pseudo
:
933 case ARM::VST3d16Pseudo
:
934 case ARM::VST3d32Pseudo
:
935 case ARM::VST1d64TPseudo
:
936 case ARM::VST3d8Pseudo_UPD
:
937 case ARM::VST3d16Pseudo_UPD
:
938 case ARM::VST3d32Pseudo_UPD
:
939 case ARM::VST1d64TPseudo_UPD
:
940 case ARM::VST3q8Pseudo_UPD
:
941 case ARM::VST3q16Pseudo_UPD
:
942 case ARM::VST3q32Pseudo_UPD
:
943 case ARM::VST3q8oddPseudo_UPD
:
944 case ARM::VST3q16oddPseudo_UPD
:
945 case ARM::VST3q32oddPseudo_UPD
:
946 case ARM::VST4d8Pseudo
:
947 case ARM::VST4d16Pseudo
:
948 case ARM::VST4d32Pseudo
:
949 case ARM::VST1d64QPseudo
:
950 case ARM::VST4d8Pseudo_UPD
:
951 case ARM::VST4d16Pseudo_UPD
:
952 case ARM::VST4d32Pseudo_UPD
:
953 case ARM::VST1d64QPseudo_UPD
:
954 case ARM::VST4q8Pseudo_UPD
:
955 case ARM::VST4q16Pseudo_UPD
:
956 case ARM::VST4q32Pseudo_UPD
:
957 case ARM::VST4q8oddPseudo_UPD
:
958 case ARM::VST4q16oddPseudo_UPD
:
959 case ARM::VST4q32oddPseudo_UPD
:
963 case ARM::VLD1LNq8Pseudo
:
964 case ARM::VLD1LNq16Pseudo
:
965 case ARM::VLD1LNq32Pseudo
:
966 case ARM::VLD1LNq8Pseudo_UPD
:
967 case ARM::VLD1LNq16Pseudo_UPD
:
968 case ARM::VLD1LNq32Pseudo_UPD
:
969 case ARM::VLD2LNd8Pseudo
:
970 case ARM::VLD2LNd16Pseudo
:
971 case ARM::VLD2LNd32Pseudo
:
972 case ARM::VLD2LNq16Pseudo
:
973 case ARM::VLD2LNq32Pseudo
:
974 case ARM::VLD2LNd8Pseudo_UPD
:
975 case ARM::VLD2LNd16Pseudo_UPD
:
976 case ARM::VLD2LNd32Pseudo_UPD
:
977 case ARM::VLD2LNq16Pseudo_UPD
:
978 case ARM::VLD2LNq32Pseudo_UPD
:
979 case ARM::VLD3LNd8Pseudo
:
980 case ARM::VLD3LNd16Pseudo
:
981 case ARM::VLD3LNd32Pseudo
:
982 case ARM::VLD3LNq16Pseudo
:
983 case ARM::VLD3LNq32Pseudo
:
984 case ARM::VLD3LNd8Pseudo_UPD
:
985 case ARM::VLD3LNd16Pseudo_UPD
:
986 case ARM::VLD3LNd32Pseudo_UPD
:
987 case ARM::VLD3LNq16Pseudo_UPD
:
988 case ARM::VLD3LNq32Pseudo_UPD
:
989 case ARM::VLD4LNd8Pseudo
:
990 case ARM::VLD4LNd16Pseudo
:
991 case ARM::VLD4LNd32Pseudo
:
992 case ARM::VLD4LNq16Pseudo
:
993 case ARM::VLD4LNq32Pseudo
:
994 case ARM::VLD4LNd8Pseudo_UPD
:
995 case ARM::VLD4LNd16Pseudo_UPD
:
996 case ARM::VLD4LNd32Pseudo_UPD
:
997 case ARM::VLD4LNq16Pseudo_UPD
:
998 case ARM::VLD4LNq32Pseudo_UPD
:
999 case ARM::VST1LNq8Pseudo
:
1000 case ARM::VST1LNq16Pseudo
:
1001 case ARM::VST1LNq32Pseudo
:
1002 case ARM::VST1LNq8Pseudo_UPD
:
1003 case ARM::VST1LNq16Pseudo_UPD
:
1004 case ARM::VST1LNq32Pseudo_UPD
:
1005 case ARM::VST2LNd8Pseudo
:
1006 case ARM::VST2LNd16Pseudo
:
1007 case ARM::VST2LNd32Pseudo
:
1008 case ARM::VST2LNq16Pseudo
:
1009 case ARM::VST2LNq32Pseudo
:
1010 case ARM::VST2LNd8Pseudo_UPD
:
1011 case ARM::VST2LNd16Pseudo_UPD
:
1012 case ARM::VST2LNd32Pseudo_UPD
:
1013 case ARM::VST2LNq16Pseudo_UPD
:
1014 case ARM::VST2LNq32Pseudo_UPD
:
1015 case ARM::VST3LNd8Pseudo
:
1016 case ARM::VST3LNd16Pseudo
:
1017 case ARM::VST3LNd32Pseudo
:
1018 case ARM::VST3LNq16Pseudo
:
1019 case ARM::VST3LNq32Pseudo
:
1020 case ARM::VST3LNd8Pseudo_UPD
:
1021 case ARM::VST3LNd16Pseudo_UPD
:
1022 case ARM::VST3LNd32Pseudo_UPD
:
1023 case ARM::VST3LNq16Pseudo_UPD
:
1024 case ARM::VST3LNq32Pseudo_UPD
:
1025 case ARM::VST4LNd8Pseudo
:
1026 case ARM::VST4LNd16Pseudo
:
1027 case ARM::VST4LNd32Pseudo
:
1028 case ARM::VST4LNq16Pseudo
:
1029 case ARM::VST4LNq32Pseudo
:
1030 case ARM::VST4LNd8Pseudo_UPD
:
1031 case ARM::VST4LNd16Pseudo_UPD
:
1032 case ARM::VST4LNd32Pseudo_UPD
:
1033 case ARM::VST4LNq16Pseudo_UPD
:
1034 case ARM::VST4LNq32Pseudo_UPD
:
1038 case ARM::VTBL2Pseudo
:
1039 ExpandVTBL(MBBI
, ARM::VTBL2
, false, 2); break;
1040 case ARM::VTBL3Pseudo
:
1041 ExpandVTBL(MBBI
, ARM::VTBL3
, false, 3); break;
1042 case ARM::VTBL4Pseudo
:
1043 ExpandVTBL(MBBI
, ARM::VTBL4
, false, 4); break;
1044 case ARM::VTBX2Pseudo
:
1045 ExpandVTBL(MBBI
, ARM::VTBX2
, true, 2); break;
1046 case ARM::VTBX3Pseudo
:
1047 ExpandVTBL(MBBI
, ARM::VTBX3
, true, 3); break;
1048 case ARM::VTBX4Pseudo
:
1049 ExpandVTBL(MBBI
, ARM::VTBX4
, true, 4); break;
1060 bool ARMExpandPseudo::runOnMachineFunction(MachineFunction
&MF
) {
1061 TII
= static_cast<const ARMBaseInstrInfo
*>(MF
.getTarget().getInstrInfo());
1062 TRI
= MF
.getTarget().getRegisterInfo();
1064 bool Modified
= false;
1065 for (MachineFunction::iterator MFI
= MF
.begin(), E
= MF
.end(); MFI
!= E
;
1067 Modified
|= ExpandMBB(*MFI
);
1071 /// createARMExpandPseudoPass - returns an instance of the pseudo instruction
1073 FunctionPass
*llvm::createARMExpandPseudoPass() {
1074 return new ARMExpandPseudo();