34#define DEBUG_TYPE "arm-pseudo"
38 cl::desc(
"Verify machine code after expanding ARM pseudos"));
40#define ARM_EXPAND_PSEUDO_NAME "ARM pseudo instruction expansion pass"
72 unsigned Opc,
bool IsExt);
112 unsigned StrexOp,
unsigned UxtOp,
119 char ARMExpandPseudo::ID = 0;
130 enum NEONRegSpacing {
141 struct NEONLdStTableEntry {
146 bool hasWritebackOperand;
155 bool copyAllListRegs;
158 bool operator<(
const NEONLdStTableEntry &TE)
const {
159 return PseudoOpc < TE.PseudoOpc;
161 friend bool operator<(
const NEONLdStTableEntry &TE,
unsigned PseudoOpc) {
162 return TE.PseudoOpc < PseudoOpc;
164 [[maybe_unused]]
friend bool operator<(
unsigned PseudoOpc,
165 const NEONLdStTableEntry &TE) {
166 return PseudoOpc < TE.PseudoOpc;
172{ ARM::VLD1LNq16Pseudo, ARM::VLD1LNd16,
true,
false,
false, EvenDblSpc, 1, 4 ,
true},
173{ ARM::VLD1LNq16Pseudo_UPD, ARM::VLD1LNd16_UPD,
true,
true,
true, EvenDblSpc, 1, 4 ,
true},
174{ ARM::VLD1LNq32Pseudo, ARM::VLD1LNd32,
true,
false,
false, EvenDblSpc, 1, 2 ,
true},
175{ ARM::VLD1LNq32Pseudo_UPD, ARM::VLD1LNd32_UPD,
true,
true,
true, EvenDblSpc, 1, 2 ,
true},
176{ ARM::VLD1LNq8Pseudo, ARM::VLD1LNd8,
true,
false,
false, EvenDblSpc, 1, 8 ,
true},
177{ ARM::VLD1LNq8Pseudo_UPD, ARM::VLD1LNd8_UPD,
true,
true,
true, EvenDblSpc, 1, 8 ,
true},
179{ ARM::VLD1d16QPseudo, ARM::VLD1d16Q,
true,
false,
false, SingleSpc, 4, 4 ,
false},
180{ ARM::VLD1d16QPseudoWB_fixed, ARM::VLD1d16Qwb_fixed,
true,
true,
false, SingleSpc, 4, 4 ,
false},
181{ ARM::VLD1d16QPseudoWB_register, ARM::VLD1d16Qwb_register,
true,
true,
true, SingleSpc, 4, 4 ,
false},
182{ ARM::VLD1d16TPseudo, ARM::VLD1d16T,
true,
false,
false, SingleSpc, 3, 4 ,
false},
183{ ARM::VLD1d16TPseudoWB_fixed, ARM::VLD1d16Twb_fixed,
true,
true,
false, SingleSpc, 3, 4 ,
false},
184{ ARM::VLD1d16TPseudoWB_register, ARM::VLD1d16Twb_register,
true,
true,
true, SingleSpc, 3, 4 ,
false},
186{ ARM::VLD1d32QPseudo, ARM::VLD1d32Q,
true,
false,
false, SingleSpc, 4, 2 ,
false},
187{ ARM::VLD1d32QPseudoWB_fixed, ARM::VLD1d32Qwb_fixed,
true,
true,
false, SingleSpc, 4, 2 ,
false},
188{ ARM::VLD1d32QPseudoWB_register, ARM::VLD1d32Qwb_register,
true,
true,
true, SingleSpc, 4, 2 ,
false},
189{ ARM::VLD1d32TPseudo, ARM::VLD1d32T,
true,
false,
false, SingleSpc, 3, 2 ,
false},
190{ ARM::VLD1d32TPseudoWB_fixed, ARM::VLD1d32Twb_fixed,
true,
true,
false, SingleSpc, 3, 2 ,
false},
191{ ARM::VLD1d32TPseudoWB_register, ARM::VLD1d32Twb_register,
true,
true,
true, SingleSpc, 3, 2 ,
false},
193{ ARM::VLD1d64QPseudo, ARM::VLD1d64Q,
true,
false,
false, SingleSpc, 4, 1 ,
false},
194{ ARM::VLD1d64QPseudoWB_fixed, ARM::VLD1d64Qwb_fixed,
true,
true,
false, SingleSpc, 4, 1 ,
false},
195{ ARM::VLD1d64QPseudoWB_register, ARM::VLD1d64Qwb_register,
true,
true,
true, SingleSpc, 4, 1 ,
false},
196{ ARM::VLD1d64TPseudo, ARM::VLD1d64T,
true,
false,
false, SingleSpc, 3, 1 ,
false},
197{ ARM::VLD1d64TPseudoWB_fixed, ARM::VLD1d64Twb_fixed,
true,
true,
false, SingleSpc, 3, 1 ,
false},
198{ ARM::VLD1d64TPseudoWB_register, ARM::VLD1d64Twb_register,
true,
true,
true, SingleSpc, 3, 1 ,
false},
200{ ARM::VLD1d8QPseudo, ARM::VLD1d8Q,
true,
false,
false, SingleSpc, 4, 8 ,
false},
201{ ARM::VLD1d8QPseudoWB_fixed, ARM::VLD1d8Qwb_fixed,
true,
true,
false, SingleSpc, 4, 8 ,
false},
202{ ARM::VLD1d8QPseudoWB_register, ARM::VLD1d8Qwb_register,
true,
true,
true, SingleSpc, 4, 8 ,
false},
203{ ARM::VLD1d8TPseudo, ARM::VLD1d8T,
true,
false,
false, SingleSpc, 3, 8 ,
false},
204{ ARM::VLD1d8TPseudoWB_fixed, ARM::VLD1d8Twb_fixed,
true,
true,
false, SingleSpc, 3, 8 ,
false},
205{ ARM::VLD1d8TPseudoWB_register, ARM::VLD1d8Twb_register,
true,
true,
true, SingleSpc, 3, 8 ,
false},
207{ ARM::VLD1q16HighQPseudo, ARM::VLD1d16Q,
true,
false,
false, SingleHighQSpc, 4, 4 ,
false},
208{ ARM::VLD1q16HighQPseudo_UPD, ARM::VLD1d16Qwb_fixed,
true,
true,
true, SingleHighQSpc, 4, 4 ,
false},
209{ ARM::VLD1q16HighTPseudo, ARM::VLD1d16T,
true,
false,
false, SingleHighTSpc, 3, 4 ,
false},
210{ ARM::VLD1q16HighTPseudo_UPD, ARM::VLD1d16Twb_fixed,
true,
true,
true, SingleHighTSpc, 3, 4 ,
false},
211{ ARM::VLD1q16LowQPseudo_UPD, ARM::VLD1d16Qwb_fixed,
true,
true,
true, SingleLowSpc, 4, 4 ,
false},
212{ ARM::VLD1q16LowTPseudo_UPD, ARM::VLD1d16Twb_fixed,
true,
true,
true, SingleLowSpc, 3, 4 ,
false},
214{ ARM::VLD1q32HighQPseudo, ARM::VLD1d32Q,
true,
false,
false, SingleHighQSpc, 4, 2 ,
false},
215{ ARM::VLD1q32HighQPseudo_UPD, ARM::VLD1d32Qwb_fixed,
true,
true,
true, SingleHighQSpc, 4, 2 ,
false},
216{ ARM::VLD1q32HighTPseudo, ARM::VLD1d32T,
true,
false,
false, SingleHighTSpc, 3, 2 ,
false},
217{ ARM::VLD1q32HighTPseudo_UPD, ARM::VLD1d32Twb_fixed,
true,
true,
true, SingleHighTSpc, 3, 2 ,
false},
218{ ARM::VLD1q32LowQPseudo_UPD, ARM::VLD1d32Qwb_fixed,
true,
true,
true, SingleLowSpc, 4, 2 ,
false},
219{ ARM::VLD1q32LowTPseudo_UPD, ARM::VLD1d32Twb_fixed,
true,
true,
true, SingleLowSpc, 3, 2 ,
false},
221{ ARM::VLD1q64HighQPseudo, ARM::VLD1d64Q,
true,
false,
false, SingleHighQSpc, 4, 1 ,
false},
222{ ARM::VLD1q64HighQPseudo_UPD, ARM::VLD1d64Qwb_fixed,
true,
true,
true, SingleHighQSpc, 4, 1 ,
false},
223{ ARM::VLD1q64HighTPseudo, ARM::VLD1d64T,
true,
false,
false, SingleHighTSpc, 3, 1 ,
false},
224{ ARM::VLD1q64HighTPseudo_UPD, ARM::VLD1d64Twb_fixed,
true,
true,
true, SingleHighTSpc, 3, 1 ,
false},
225{ ARM::VLD1q64LowQPseudo_UPD, ARM::VLD1d64Qwb_fixed,
true,
true,
true, SingleLowSpc, 4, 1 ,
false},
226{ ARM::VLD1q64LowTPseudo_UPD, ARM::VLD1d64Twb_fixed,
true,
true,
true, SingleLowSpc, 3, 1 ,
false},
228{ ARM::VLD1q8HighQPseudo, ARM::VLD1d8Q,
true,
false,
false, SingleHighQSpc, 4, 8 ,
false},
229{ ARM::VLD1q8HighQPseudo_UPD, ARM::VLD1d8Qwb_fixed,
true,
true,
true, SingleHighQSpc, 4, 8 ,
false},
230{ ARM::VLD1q8HighTPseudo, ARM::VLD1d8T,
true,
false,
false, SingleHighTSpc, 3, 8 ,
false},
231{ ARM::VLD1q8HighTPseudo_UPD, ARM::VLD1d8Twb_fixed,
true,
true,
true, SingleHighTSpc, 3, 8 ,
false},
232{ ARM::VLD1q8LowQPseudo_UPD, ARM::VLD1d8Qwb_fixed,
true,
true,
true, SingleLowSpc, 4, 8 ,
false},
233{ ARM::VLD1q8LowTPseudo_UPD, ARM::VLD1d8Twb_fixed,
true,
true,
true, SingleLowSpc, 3, 8 ,
false},
235{ ARM::VLD2DUPq16EvenPseudo, ARM::VLD2DUPd16x2,
true,
false,
false, EvenDblSpc, 2, 4 ,
false},
236{ ARM::VLD2DUPq16OddPseudo, ARM::VLD2DUPd16x2,
true,
false,
false, OddDblSpc, 2, 4 ,
false},
237{ ARM::VLD2DUPq16OddPseudoWB_fixed, ARM::VLD2DUPd16x2wb_fixed,
true,
true,
false, OddDblSpc, 2, 4 ,
false},
238{ ARM::VLD2DUPq16OddPseudoWB_register, ARM::VLD2DUPd16x2wb_register,
true,
true,
true, OddDblSpc, 2, 4 ,
false},
239{ ARM::VLD2DUPq32EvenPseudo, ARM::VLD2DUPd32x2,
true,
false,
false, EvenDblSpc, 2, 2 ,
false},
240{ ARM::VLD2DUPq32OddPseudo, ARM::VLD2DUPd32x2,
true,
false,
false, OddDblSpc, 2, 2 ,
false},
241{ ARM::VLD2DUPq32OddPseudoWB_fixed, ARM::VLD2DUPd32x2wb_fixed,
true,
true,
false, OddDblSpc, 2, 2 ,
false},
242{ ARM::VLD2DUPq32OddPseudoWB_register, ARM::VLD2DUPd32x2wb_register,
true,
true,
true, OddDblSpc, 2, 2 ,
false},
243{ ARM::VLD2DUPq8EvenPseudo, ARM::VLD2DUPd8x2,
true,
false,
false, EvenDblSpc, 2, 8 ,
false},
244{ ARM::VLD2DUPq8OddPseudo, ARM::VLD2DUPd8x2,
true,
false,
false, OddDblSpc, 2, 8 ,
false},
245{ ARM::VLD2DUPq8OddPseudoWB_fixed, ARM::VLD2DUPd8x2wb_fixed,
true,
true,
false, OddDblSpc, 2, 8 ,
false},
246{ ARM::VLD2DUPq8OddPseudoWB_register, ARM::VLD2DUPd8x2wb_register,
true,
true,
true, OddDblSpc, 2, 8 ,
false},
248{ ARM::VLD2LNd16Pseudo, ARM::VLD2LNd16,
true,
false,
false, SingleSpc, 2, 4 ,
true},
249{ ARM::VLD2LNd16Pseudo_UPD, ARM::VLD2LNd16_UPD,
true,
true,
true, SingleSpc, 2, 4 ,
true},
250{ ARM::VLD2LNd32Pseudo, ARM::VLD2LNd32,
true,
false,
false, SingleSpc, 2, 2 ,
true},
251{ ARM::VLD2LNd32Pseudo_UPD, ARM::VLD2LNd32_UPD,
true,
true,
true, SingleSpc, 2, 2 ,
true},
252{ ARM::VLD2LNd8Pseudo, ARM::VLD2LNd8,
true,
false,
false, SingleSpc, 2, 8 ,
true},
253{ ARM::VLD2LNd8Pseudo_UPD, ARM::VLD2LNd8_UPD,
true,
true,
true, SingleSpc, 2, 8 ,
true},
254{ ARM::VLD2LNq16Pseudo, ARM::VLD2LNq16,
true,
false,
false, EvenDblSpc, 2, 4 ,
true},
255{ ARM::VLD2LNq16Pseudo_UPD, ARM::VLD2LNq16_UPD,
true,
true,
true, EvenDblSpc, 2, 4 ,
true},
256{ ARM::VLD2LNq32Pseudo, ARM::VLD2LNq32,
true,
false,
false, EvenDblSpc, 2, 2 ,
true},
257{ ARM::VLD2LNq32Pseudo_UPD, ARM::VLD2LNq32_UPD,
true,
true,
true, EvenDblSpc, 2, 2 ,
true},
259{ ARM::VLD2q16Pseudo, ARM::VLD2q16,
true,
false,
false, SingleSpc, 4, 4 ,
false},
260{ ARM::VLD2q16PseudoWB_fixed, ARM::VLD2q16wb_fixed,
true,
true,
false, SingleSpc, 4, 4 ,
false},
261{ ARM::VLD2q16PseudoWB_register, ARM::VLD2q16wb_register,
true,
true,
true, SingleSpc, 4, 4 ,
false},
262{ ARM::VLD2q32Pseudo, ARM::VLD2q32,
true,
false,
false, SingleSpc, 4, 2 ,
false},
263{ ARM::VLD2q32PseudoWB_fixed, ARM::VLD2q32wb_fixed,
true,
true,
false, SingleSpc, 4, 2 ,
false},
264{ ARM::VLD2q32PseudoWB_register, ARM::VLD2q32wb_register,
true,
true,
true, SingleSpc, 4, 2 ,
false},
265{ ARM::VLD2q8Pseudo, ARM::VLD2q8,
true,
false,
false, SingleSpc, 4, 8 ,
false},
266{ ARM::VLD2q8PseudoWB_fixed, ARM::VLD2q8wb_fixed,
true,
true,
false, SingleSpc, 4, 8 ,
false},
267{ ARM::VLD2q8PseudoWB_register, ARM::VLD2q8wb_register,
true,
true,
true, SingleSpc, 4, 8 ,
false},
269{ ARM::VLD3DUPd16Pseudo, ARM::VLD3DUPd16,
true,
false,
false, SingleSpc, 3, 4,
true},
270{ ARM::VLD3DUPd16Pseudo_UPD, ARM::VLD3DUPd16_UPD,
true,
true,
true, SingleSpc, 3, 4,
true},
271{ ARM::VLD3DUPd32Pseudo, ARM::VLD3DUPd32,
true,
false,
false, SingleSpc, 3, 2,
true},
272{ ARM::VLD3DUPd32Pseudo_UPD, ARM::VLD3DUPd32_UPD,
true,
true,
true, SingleSpc, 3, 2,
true},
273{ ARM::VLD3DUPd8Pseudo, ARM::VLD3DUPd8,
true,
false,
false, SingleSpc, 3, 8,
true},
274{ ARM::VLD3DUPd8Pseudo_UPD, ARM::VLD3DUPd8_UPD,
true,
true,
true, SingleSpc, 3, 8,
true},
275{ ARM::VLD3DUPq16EvenPseudo, ARM::VLD3DUPq16,
true,
false,
false, EvenDblSpc, 3, 4 ,
true},
276{ ARM::VLD3DUPq16OddPseudo, ARM::VLD3DUPq16,
true,
false,
false, OddDblSpc, 3, 4 ,
true},
277{ ARM::VLD3DUPq16OddPseudo_UPD, ARM::VLD3DUPq16_UPD,
true,
true,
true, OddDblSpc, 3, 4 ,
true},
278{ ARM::VLD3DUPq32EvenPseudo, ARM::VLD3DUPq32,
true,
false,
false, EvenDblSpc, 3, 2 ,
true},
279{ ARM::VLD3DUPq32OddPseudo, ARM::VLD3DUPq32,
true,
false,
false, OddDblSpc, 3, 2 ,
true},
280{ ARM::VLD3DUPq32OddPseudo_UPD, ARM::VLD3DUPq32_UPD,
true,
true,
true, OddDblSpc, 3, 2 ,
true},
281{ ARM::VLD3DUPq8EvenPseudo, ARM::VLD3DUPq8,
true,
false,
false, EvenDblSpc, 3, 8 ,
true},
282{ ARM::VLD3DUPq8OddPseudo, ARM::VLD3DUPq8,
true,
false,
false, OddDblSpc, 3, 8 ,
true},
283{ ARM::VLD3DUPq8OddPseudo_UPD, ARM::VLD3DUPq8_UPD,
true,
true,
true, OddDblSpc, 3, 8 ,
true},
285{ ARM::VLD3LNd16Pseudo, ARM::VLD3LNd16,
true,
false,
false, SingleSpc, 3, 4 ,
true},
286{ ARM::VLD3LNd16Pseudo_UPD, ARM::VLD3LNd16_UPD,
true,
true,
true, SingleSpc, 3, 4 ,
true},
287{ ARM::VLD3LNd32Pseudo, ARM::VLD3LNd32,
true,
false,
false, SingleSpc, 3, 2 ,
true},
288{ ARM::VLD3LNd32Pseudo_UPD, ARM::VLD3LNd32_UPD,
true,
true,
true, SingleSpc, 3, 2 ,
true},
289{ ARM::VLD3LNd8Pseudo, ARM::VLD3LNd8,
true,
false,
false, SingleSpc, 3, 8 ,
true},
290{ ARM::VLD3LNd8Pseudo_UPD, ARM::VLD3LNd8_UPD,
true,
true,
true, SingleSpc, 3, 8 ,
true},
291{ ARM::VLD3LNq16Pseudo, ARM::VLD3LNq16,
true,
false,
false, EvenDblSpc, 3, 4 ,
true},
292{ ARM::VLD3LNq16Pseudo_UPD, ARM::VLD3LNq16_UPD,
true,
true,
true, EvenDblSpc, 3, 4 ,
true},
293{ ARM::VLD3LNq32Pseudo, ARM::VLD3LNq32,
true,
false,
false, EvenDblSpc, 3, 2 ,
true},
294{ ARM::VLD3LNq32Pseudo_UPD, ARM::VLD3LNq32_UPD,
true,
true,
true, EvenDblSpc, 3, 2 ,
true},
296{ ARM::VLD3d16Pseudo, ARM::VLD3d16,
true,
false,
false, SingleSpc, 3, 4 ,
true},
297{ ARM::VLD3d16Pseudo_UPD, ARM::VLD3d16_UPD,
true,
true,
true, SingleSpc, 3, 4 ,
true},
298{ ARM::VLD3d32Pseudo, ARM::VLD3d32,
true,
false,
false, SingleSpc, 3, 2 ,
true},
299{ ARM::VLD3d32Pseudo_UPD, ARM::VLD3d32_UPD,
true,
true,
true, SingleSpc, 3, 2 ,
true},
300{ ARM::VLD3d8Pseudo, ARM::VLD3d8,
true,
false,
false, SingleSpc, 3, 8 ,
true},
301{ ARM::VLD3d8Pseudo_UPD, ARM::VLD3d8_UPD,
true,
true,
true, SingleSpc, 3, 8 ,
true},
303{ ARM::VLD3q16Pseudo_UPD, ARM::VLD3q16_UPD,
true,
true,
true, EvenDblSpc, 3, 4 ,
true},
304{ ARM::VLD3q16oddPseudo, ARM::VLD3q16,
true,
false,
false, OddDblSpc, 3, 4 ,
true},
305{ ARM::VLD3q16oddPseudo_UPD, ARM::VLD3q16_UPD,
true,
true,
true, OddDblSpc, 3, 4 ,
true},
306{ ARM::VLD3q32Pseudo_UPD, ARM::VLD3q32_UPD,
true,
true,
true, EvenDblSpc, 3, 2 ,
true},
307{ ARM::VLD3q32oddPseudo, ARM::VLD3q32,
true,
false,
false, OddDblSpc, 3, 2 ,
true},
308{ ARM::VLD3q32oddPseudo_UPD, ARM::VLD3q32_UPD,
true,
true,
true, OddDblSpc, 3, 2 ,
true},
309{ ARM::VLD3q8Pseudo_UPD, ARM::VLD3q8_UPD,
true,
true,
true, EvenDblSpc, 3, 8 ,
true},
310{ ARM::VLD3q8oddPseudo, ARM::VLD3q8,
true,
false,
false, OddDblSpc, 3, 8 ,
true},
311{ ARM::VLD3q8oddPseudo_UPD, ARM::VLD3q8_UPD,
true,
true,
true, OddDblSpc, 3, 8 ,
true},
313{ ARM::VLD4DUPd16Pseudo, ARM::VLD4DUPd16,
true,
false,
false, SingleSpc, 4, 4,
true},
314{ ARM::VLD4DUPd16Pseudo_UPD, ARM::VLD4DUPd16_UPD,
true,
true,
true, SingleSpc, 4, 4,
true},
315{ ARM::VLD4DUPd32Pseudo, ARM::VLD4DUPd32,
true,
false,
false, SingleSpc, 4, 2,
true},
316{ ARM::VLD4DUPd32Pseudo_UPD, ARM::VLD4DUPd32_UPD,
true,
true,
true, SingleSpc, 4, 2,
true},
317{ ARM::VLD4DUPd8Pseudo, ARM::VLD4DUPd8,
true,
false,
false, SingleSpc, 4, 8,
true},
318{ ARM::VLD4DUPd8Pseudo_UPD, ARM::VLD4DUPd8_UPD,
true,
true,
true, SingleSpc, 4, 8,
true},
319{ ARM::VLD4DUPq16EvenPseudo, ARM::VLD4DUPq16,
true,
false,
false, EvenDblSpc, 4, 4 ,
true},
320{ ARM::VLD4DUPq16OddPseudo, ARM::VLD4DUPq16,
true,
false,
false, OddDblSpc, 4, 4 ,
true},
321{ ARM::VLD4DUPq16OddPseudo_UPD, ARM::VLD4DUPq16_UPD,
true,
true,
true, OddDblSpc, 4, 4 ,
true},
322{ ARM::VLD4DUPq32EvenPseudo, ARM::VLD4DUPq32,
true,
false,
false, EvenDblSpc, 4, 2 ,
true},
323{ ARM::VLD4DUPq32OddPseudo, ARM::VLD4DUPq32,
true,
false,
false, OddDblSpc, 4, 2 ,
true},
324{ ARM::VLD4DUPq32OddPseudo_UPD, ARM::VLD4DUPq32_UPD,
true,
true,
true, OddDblSpc, 4, 2 ,
true},
325{ ARM::VLD4DUPq8EvenPseudo, ARM::VLD4DUPq8,
true,
false,
false, EvenDblSpc, 4, 8 ,
true},
326{ ARM::VLD4DUPq8OddPseudo, ARM::VLD4DUPq8,
true,
false,
false, OddDblSpc, 4, 8 ,
true},
327{ ARM::VLD4DUPq8OddPseudo_UPD, ARM::VLD4DUPq8_UPD,
true,
true,
true, OddDblSpc, 4, 8 ,
true},
329{ ARM::VLD4LNd16Pseudo, ARM::VLD4LNd16,
true,
false,
false, SingleSpc, 4, 4 ,
true},
330{ ARM::VLD4LNd16Pseudo_UPD, ARM::VLD4LNd16_UPD,
true,
true,
true, SingleSpc, 4, 4 ,
true},
331{ ARM::VLD4LNd32Pseudo, ARM::VLD4LNd32,
true,
false,
false, SingleSpc, 4, 2 ,
true},
332{ ARM::VLD4LNd32Pseudo_UPD, ARM::VLD4LNd32_UPD,
true,
true,
true, SingleSpc, 4, 2 ,
true},
333{ ARM::VLD4LNd8Pseudo, ARM::VLD4LNd8,
true,
false,
false, SingleSpc, 4, 8 ,
true},
334{ ARM::VLD4LNd8Pseudo_UPD, ARM::VLD4LNd8_UPD,
true,
true,
true, SingleSpc, 4, 8 ,
true},
335{ ARM::VLD4LNq16Pseudo, ARM::VLD4LNq16,
true,
false,
false, EvenDblSpc, 4, 4 ,
true},
336{ ARM::VLD4LNq16Pseudo_UPD, ARM::VLD4LNq16_UPD,
true,
true,
true, EvenDblSpc, 4, 4 ,
true},
337{ ARM::VLD4LNq32Pseudo, ARM::VLD4LNq32,
true,
false,
false, EvenDblSpc, 4, 2 ,
true},
338{ ARM::VLD4LNq32Pseudo_UPD, ARM::VLD4LNq32_UPD,
true,
true,
true, EvenDblSpc, 4, 2 ,
true},
340{ ARM::VLD4d16Pseudo, ARM::VLD4d16,
true,
false,
false, SingleSpc, 4, 4 ,
true},
341{ ARM::VLD4d16Pseudo_UPD, ARM::VLD4d16_UPD,
true,
true,
true, SingleSpc, 4, 4 ,
true},
342{ ARM::VLD4d32Pseudo, ARM::VLD4d32,
true,
false,
false, SingleSpc, 4, 2 ,
true},
343{ ARM::VLD4d32Pseudo_UPD, ARM::VLD4d32_UPD,
true,
true,
true, SingleSpc, 4, 2 ,
true},
344{ ARM::VLD4d8Pseudo, ARM::VLD4d8,
true,
false,
false, SingleSpc, 4, 8 ,
true},
345{ ARM::VLD4d8Pseudo_UPD, ARM::VLD4d8_UPD,
true,
true,
true, SingleSpc, 4, 8 ,
true},
347{ ARM::VLD4q16Pseudo_UPD, ARM::VLD4q16_UPD,
true,
true,
true, EvenDblSpc, 4, 4 ,
true},
348{ ARM::VLD4q16oddPseudo, ARM::VLD4q16,
true,
false,
false, OddDblSpc, 4, 4 ,
true},
349{ ARM::VLD4q16oddPseudo_UPD, ARM::VLD4q16_UPD,
true,
true,
true, OddDblSpc, 4, 4 ,
true},
350{ ARM::VLD4q32Pseudo_UPD, ARM::VLD4q32_UPD,
true,
true,
true, EvenDblSpc, 4, 2 ,
true},
351{ ARM::VLD4q32oddPseudo, ARM::VLD4q32,
true,
false,
false, OddDblSpc, 4, 2 ,
true},
352{ ARM::VLD4q32oddPseudo_UPD, ARM::VLD4q32_UPD,
true,
true,
true, OddDblSpc, 4, 2 ,
true},
353{ ARM::VLD4q8Pseudo_UPD, ARM::VLD4q8_UPD,
true,
true,
true, EvenDblSpc, 4, 8 ,
true},
354{ ARM::VLD4q8oddPseudo, ARM::VLD4q8,
true,
false,
false, OddDblSpc, 4, 8 ,
true},
355{ ARM::VLD4q8oddPseudo_UPD, ARM::VLD4q8_UPD,
true,
true,
true, OddDblSpc, 4, 8 ,
true},
357{ ARM::VST1LNq16Pseudo, ARM::VST1LNd16,
false,
false,
false, EvenDblSpc, 1, 4 ,
true},
358{ ARM::VST1LNq16Pseudo_UPD, ARM::VST1LNd16_UPD,
false,
true,
true, EvenDblSpc, 1, 4 ,
true},
359{ ARM::VST1LNq32Pseudo, ARM::VST1LNd32,
false,
false,
false, EvenDblSpc, 1, 2 ,
true},
360{ ARM::VST1LNq32Pseudo_UPD, ARM::VST1LNd32_UPD,
false,
true,
true, EvenDblSpc, 1, 2 ,
true},
361{ ARM::VST1LNq8Pseudo, ARM::VST1LNd8,
false,
false,
false, EvenDblSpc, 1, 8 ,
true},
362{ ARM::VST1LNq8Pseudo_UPD, ARM::VST1LNd8_UPD,
false,
true,
true, EvenDblSpc, 1, 8 ,
true},
364{ ARM::VST1d16QPseudo, ARM::VST1d16Q,
false,
false,
false, SingleSpc, 4, 4 ,
false},
365{ ARM::VST1d16QPseudoWB_fixed, ARM::VST1d16Qwb_fixed,
false,
true,
false, SingleSpc, 4, 4 ,
false},
366{ ARM::VST1d16QPseudoWB_register, ARM::VST1d16Qwb_register,
false,
true,
true, SingleSpc, 4, 4 ,
false},
367{ ARM::VST1d16TPseudo, ARM::VST1d16T,
false,
false,
false, SingleSpc, 3, 4 ,
false},
368{ ARM::VST1d16TPseudoWB_fixed, ARM::VST1d16Twb_fixed,
false,
true,
false, SingleSpc, 3, 4 ,
false},
369{ ARM::VST1d16TPseudoWB_register, ARM::VST1d16Twb_register,
false,
true,
true, SingleSpc, 3, 4 ,
false},
371{ ARM::VST1d32QPseudo, ARM::VST1d32Q,
false,
false,
false, SingleSpc, 4, 2 ,
false},
372{ ARM::VST1d32QPseudoWB_fixed, ARM::VST1d32Qwb_fixed,
false,
true,
false, SingleSpc, 4, 2 ,
false},
373{ ARM::VST1d32QPseudoWB_register, ARM::VST1d32Qwb_register,
false,
true,
true, SingleSpc, 4, 2 ,
false},
374{ ARM::VST1d32TPseudo, ARM::VST1d32T,
false,
false,
false, SingleSpc, 3, 2 ,
false},
375{ ARM::VST1d32TPseudoWB_fixed, ARM::VST1d32Twb_fixed,
false,
true,
false, SingleSpc, 3, 2 ,
false},
376{ ARM::VST1d32TPseudoWB_register, ARM::VST1d32Twb_register,
false,
true,
true, SingleSpc, 3, 2 ,
false},
378{ ARM::VST1d64QPseudo, ARM::VST1d64Q,
false,
false,
false, SingleSpc, 4, 1 ,
false},
379{ ARM::VST1d64QPseudoWB_fixed, ARM::VST1d64Qwb_fixed,
false,
true,
false, SingleSpc, 4, 1 ,
false},
380{ ARM::VST1d64QPseudoWB_register, ARM::VST1d64Qwb_register,
false,
true,
true, SingleSpc, 4, 1 ,
false},
381{ ARM::VST1d64TPseudo, ARM::VST1d64T,
false,
false,
false, SingleSpc, 3, 1 ,
false},
382{ ARM::VST1d64TPseudoWB_fixed, ARM::VST1d64Twb_fixed,
false,
true,
false, SingleSpc, 3, 1 ,
false},
383{ ARM::VST1d64TPseudoWB_register, ARM::VST1d64Twb_register,
false,
true,
true, SingleSpc, 3, 1 ,
false},
385{ ARM::VST1d8QPseudo, ARM::VST1d8Q,
false,
false,
false, SingleSpc, 4, 8 ,
false},
386{ ARM::VST1d8QPseudoWB_fixed, ARM::VST1d8Qwb_fixed,
false,
true,
false, SingleSpc, 4, 8 ,
false},
387{ ARM::VST1d8QPseudoWB_register, ARM::VST1d8Qwb_register,
false,
true,
true, SingleSpc, 4, 8 ,
false},
388{ ARM::VST1d8TPseudo, ARM::VST1d8T,
false,
false,
false, SingleSpc, 3, 8 ,
false},
389{ ARM::VST1d8TPseudoWB_fixed, ARM::VST1d8Twb_fixed,
false,
true,
false, SingleSpc, 3, 8 ,
false},
390{ ARM::VST1d8TPseudoWB_register, ARM::VST1d8Twb_register,
false,
true,
true, SingleSpc, 3, 8 ,
false},
392{ ARM::VST1q16HighQPseudo, ARM::VST1d16Q,
false,
false,
false, SingleHighQSpc, 4, 4 ,
false},
393{ ARM::VST1q16HighQPseudo_UPD, ARM::VST1d16Qwb_fixed,
false,
true,
true, SingleHighQSpc, 4, 8 ,
false},
394{ ARM::VST1q16HighTPseudo, ARM::VST1d16T,
false,
false,
false, SingleHighTSpc, 3, 4 ,
false},
395{ ARM::VST1q16HighTPseudo_UPD, ARM::VST1d16Twb_fixed,
false,
true,
true, SingleHighTSpc, 3, 4 ,
false},
396{ ARM::VST1q16LowQPseudo_UPD, ARM::VST1d16Qwb_fixed,
false,
true,
true, SingleLowSpc, 4, 4 ,
false},
397{ ARM::VST1q16LowTPseudo_UPD, ARM::VST1d16Twb_fixed,
false,
true,
true, SingleLowSpc, 3, 4 ,
false},
399{ ARM::VST1q32HighQPseudo, ARM::VST1d32Q,
false,
false,
false, SingleHighQSpc, 4, 2 ,
false},
400{ ARM::VST1q32HighQPseudo_UPD, ARM::VST1d32Qwb_fixed,
false,
true,
true, SingleHighQSpc, 4, 8 ,
false},
401{ ARM::VST1q32HighTPseudo, ARM::VST1d32T,
false,
false,
false, SingleHighTSpc, 3, 2 ,
false},
402{ ARM::VST1q32HighTPseudo_UPD, ARM::VST1d32Twb_fixed,
false,
true,
true, SingleHighTSpc, 3, 2 ,
false},
403{ ARM::VST1q32LowQPseudo_UPD, ARM::VST1d32Qwb_fixed,
false,
true,
true, SingleLowSpc, 4, 2 ,
false},
404{ ARM::VST1q32LowTPseudo_UPD, ARM::VST1d32Twb_fixed,
false,
true,
true, SingleLowSpc, 3, 2 ,
false},
406{ ARM::VST1q64HighQPseudo, ARM::VST1d64Q,
false,
false,
false, SingleHighQSpc, 4, 1 ,
false},
407{ ARM::VST1q64HighQPseudo_UPD, ARM::VST1d64Qwb_fixed,
false,
true,
true, SingleHighQSpc, 4, 8 ,
false},
408{ ARM::VST1q64HighTPseudo, ARM::VST1d64T,
false,
false,
false, SingleHighTSpc, 3, 1 ,
false},
409{ ARM::VST1q64HighTPseudo_UPD, ARM::VST1d64Twb_fixed,
false,
true,
true, SingleHighTSpc, 3, 1 ,
false},
410{ ARM::VST1q64LowQPseudo_UPD, ARM::VST1d64Qwb_fixed,
false,
true,
true, SingleLowSpc, 4, 1 ,
false},
411{ ARM::VST1q64LowTPseudo_UPD, ARM::VST1d64Twb_fixed,
false,
true,
true, SingleLowSpc, 3, 1 ,
false},
413{ ARM::VST1q8HighQPseudo, ARM::VST1d8Q,
false,
false,
false, SingleHighQSpc, 4, 8 ,
false},
414{ ARM::VST1q8HighQPseudo_UPD, ARM::VST1d8Qwb_fixed,
false,
true,
true, SingleHighQSpc, 4, 8 ,
false},
415{ ARM::VST1q8HighTPseudo, ARM::VST1d8T,
false,
false,
false, SingleHighTSpc, 3, 8 ,
false},
416{ ARM::VST1q8HighTPseudo_UPD, ARM::VST1d8Twb_fixed,
false,
true,
true, SingleHighTSpc, 3, 8 ,
false},
417{ ARM::VST1q8LowQPseudo_UPD, ARM::VST1d8Qwb_fixed,
false,
true,
true, SingleLowSpc, 4, 8 ,
false},
418{ ARM::VST1q8LowTPseudo_UPD, ARM::VST1d8Twb_fixed,
false,
true,
true, SingleLowSpc, 3, 8 ,
false},
420{ ARM::VST2LNd16Pseudo, ARM::VST2LNd16,
false,
false,
false, SingleSpc, 2, 4 ,
true},
421{ ARM::VST2LNd16Pseudo_UPD, ARM::VST2LNd16_UPD,
false,
true,
true, SingleSpc, 2, 4 ,
true},
422{ ARM::VST2LNd32Pseudo, ARM::VST2LNd32,
false,
false,
false, SingleSpc, 2, 2 ,
true},
423{ ARM::VST2LNd32Pseudo_UPD, ARM::VST2LNd32_UPD,
false,
true,
true, SingleSpc, 2, 2 ,
true},
424{ ARM::VST2LNd8Pseudo, ARM::VST2LNd8,
false,
false,
false, SingleSpc, 2, 8 ,
true},
425{ ARM::VST2LNd8Pseudo_UPD, ARM::VST2LNd8_UPD,
false,
true,
true, SingleSpc, 2, 8 ,
true},
426{ ARM::VST2LNq16Pseudo, ARM::VST2LNq16,
false,
false,
false, EvenDblSpc, 2, 4,
true},
427{ ARM::VST2LNq16Pseudo_UPD, ARM::VST2LNq16_UPD,
false,
true,
true, EvenDblSpc, 2, 4,
true},
428{ ARM::VST2LNq32Pseudo, ARM::VST2LNq32,
false,
false,
false, EvenDblSpc, 2, 2,
true},
429{ ARM::VST2LNq32Pseudo_UPD, ARM::VST2LNq32_UPD,
false,
true,
true, EvenDblSpc, 2, 2,
true},
431{ ARM::VST2q16Pseudo, ARM::VST2q16,
false,
false,
false, SingleSpc, 4, 4 ,
false},
432{ ARM::VST2q16PseudoWB_fixed, ARM::VST2q16wb_fixed,
false,
true,
false, SingleSpc, 4, 4 ,
false},
433{ ARM::VST2q16PseudoWB_register, ARM::VST2q16wb_register,
false,
true,
true, SingleSpc, 4, 4 ,
false},
434{ ARM::VST2q32Pseudo, ARM::VST2q32,
false,
false,
false, SingleSpc, 4, 2 ,
false},
435{ ARM::VST2q32PseudoWB_fixed, ARM::VST2q32wb_fixed,
false,
true,
false, SingleSpc, 4, 2 ,
false},
436{ ARM::VST2q32PseudoWB_register, ARM::VST2q32wb_register,
false,
true,
true, SingleSpc, 4, 2 ,
false},
437{ ARM::VST2q8Pseudo, ARM::VST2q8,
false,
false,
false, SingleSpc, 4, 8 ,
false},
438{ ARM::VST2q8PseudoWB_fixed, ARM::VST2q8wb_fixed,
false,
true,
false, SingleSpc, 4, 8 ,
false},
439{ ARM::VST2q8PseudoWB_register, ARM::VST2q8wb_register,
false,
true,
true, SingleSpc, 4, 8 ,
false},
441{ ARM::VST3LNd16Pseudo, ARM::VST3LNd16,
false,
false,
false, SingleSpc, 3, 4 ,
true},
442{ ARM::VST3LNd16Pseudo_UPD, ARM::VST3LNd16_UPD,
false,
true,
true, SingleSpc, 3, 4 ,
true},
443{ ARM::VST3LNd32Pseudo, ARM::VST3LNd32,
false,
false,
false, SingleSpc, 3, 2 ,
true},
444{ ARM::VST3LNd32Pseudo_UPD, ARM::VST3LNd32_UPD,
false,
true,
true, SingleSpc, 3, 2 ,
true},
445{ ARM::VST3LNd8Pseudo, ARM::VST3LNd8,
false,
false,
false, SingleSpc, 3, 8 ,
true},
446{ ARM::VST3LNd8Pseudo_UPD, ARM::VST3LNd8_UPD,
false,
true,
true, SingleSpc, 3, 8 ,
true},
447{ ARM::VST3LNq16Pseudo, ARM::VST3LNq16,
false,
false,
false, EvenDblSpc, 3, 4,
true},
448{ ARM::VST3LNq16Pseudo_UPD, ARM::VST3LNq16_UPD,
false,
true,
true, EvenDblSpc, 3, 4,
true},
449{ ARM::VST3LNq32Pseudo, ARM::VST3LNq32,
false,
false,
false, EvenDblSpc, 3, 2,
true},
450{ ARM::VST3LNq32Pseudo_UPD, ARM::VST3LNq32_UPD,
false,
true,
true, EvenDblSpc, 3, 2,
true},
452{ ARM::VST3d16Pseudo, ARM::VST3d16,
false,
false,
false, SingleSpc, 3, 4 ,
true},
453{ ARM::VST3d16Pseudo_UPD, ARM::VST3d16_UPD,
false,
true,
true, SingleSpc, 3, 4 ,
true},
454{ ARM::VST3d32Pseudo, ARM::VST3d32,
false,
false,
false, SingleSpc, 3, 2 ,
true},
455{ ARM::VST3d32Pseudo_UPD, ARM::VST3d32_UPD,
false,
true,
true, SingleSpc, 3, 2 ,
true},
456{ ARM::VST3d8Pseudo, ARM::VST3d8,
false,
false,
false, SingleSpc, 3, 8 ,
true},
457{ ARM::VST3d8Pseudo_UPD, ARM::VST3d8_UPD,
false,
true,
true, SingleSpc, 3, 8 ,
true},
459{ ARM::VST3q16Pseudo_UPD, ARM::VST3q16_UPD,
false,
true,
true, EvenDblSpc, 3, 4 ,
true},
460{ ARM::VST3q16oddPseudo, ARM::VST3q16,
false,
false,
false, OddDblSpc, 3, 4 ,
true},
461{ ARM::VST3q16oddPseudo_UPD, ARM::VST3q16_UPD,
false,
true,
true, OddDblSpc, 3, 4 ,
true},
462{ ARM::VST3q32Pseudo_UPD, ARM::VST3q32_UPD,
false,
true,
true, EvenDblSpc, 3, 2 ,
true},
463{ ARM::VST3q32oddPseudo, ARM::VST3q32,
false,
false,
false, OddDblSpc, 3, 2 ,
true},
464{ ARM::VST3q32oddPseudo_UPD, ARM::VST3q32_UPD,
false,
true,
true, OddDblSpc, 3, 2 ,
true},
465{ ARM::VST3q8Pseudo_UPD, ARM::VST3q8_UPD,
false,
true,
true, EvenDblSpc, 3, 8 ,
true},
466{ ARM::VST3q8oddPseudo, ARM::VST3q8,
false,
false,
false, OddDblSpc, 3, 8 ,
true},
467{ ARM::VST3q8oddPseudo_UPD, ARM::VST3q8_UPD,
false,
true,
true, OddDblSpc, 3, 8 ,
true},
469{ ARM::VST4LNd16Pseudo, ARM::VST4LNd16,
false,
false,
false, SingleSpc, 4, 4 ,
true},
470{ ARM::VST4LNd16Pseudo_UPD, ARM::VST4LNd16_UPD,
false,
true,
true, SingleSpc, 4, 4 ,
true},
471{ ARM::VST4LNd32Pseudo, ARM::VST4LNd32,
false,
false,
false, SingleSpc, 4, 2 ,
true},
472{ ARM::VST4LNd32Pseudo_UPD, ARM::VST4LNd32_UPD,
false,
true,
true, SingleSpc, 4, 2 ,
true},
473{ ARM::VST4LNd8Pseudo, ARM::VST4LNd8,
false,
false,
false, SingleSpc, 4, 8 ,
true},
474{ ARM::VST4LNd8Pseudo_UPD, ARM::VST4LNd8_UPD,
false,
true,
true, SingleSpc, 4, 8 ,
true},
475{ ARM::VST4LNq16Pseudo, ARM::VST4LNq16,
false,
false,
false, EvenDblSpc, 4, 4,
true},
476{ ARM::VST4LNq16Pseudo_UPD, ARM::VST4LNq16_UPD,
false,
true,
true, EvenDblSpc, 4, 4,
true},
477{ ARM::VST4LNq32Pseudo, ARM::VST4LNq32,
false,
false,
false, EvenDblSpc, 4, 2,
true},
478{ ARM::VST4LNq32Pseudo_UPD, ARM::VST4LNq32_UPD,
false,
true,
true, EvenDblSpc, 4, 2,
true},
480{ ARM::VST4d16Pseudo, ARM::VST4d16,
false,
false,
false, SingleSpc, 4, 4 ,
true},
481{ ARM::VST4d16Pseudo_UPD, ARM::VST4d16_UPD,
false,
true,
true, SingleSpc, 4, 4 ,
true},
482{ ARM::VST4d32Pseudo, ARM::VST4d32,
false,
false,
false, SingleSpc, 4, 2 ,
true},
483{ ARM::VST4d32Pseudo_UPD, ARM::VST4d32_UPD,
false,
true,
true, SingleSpc, 4, 2 ,
true},
484{ ARM::VST4d8Pseudo, ARM::VST4d8,
false,
false,
false, SingleSpc, 4, 8 ,
true},
485{ ARM::VST4d8Pseudo_UPD, ARM::VST4d8_UPD,
false,
true,
true, SingleSpc, 4, 8 ,
true},
487{ ARM::VST4q16Pseudo_UPD, ARM::VST4q16_UPD,
false,
true,
true, EvenDblSpc, 4, 4 ,
true},
488{ ARM::VST4q16oddPseudo, ARM::VST4q16,
false,
false,
false, OddDblSpc, 4, 4 ,
true},
489{ ARM::VST4q16oddPseudo_UPD, ARM::VST4q16_UPD,
false,
true,
true, OddDblSpc, 4, 4 ,
true},
490{ ARM::VST4q32Pseudo_UPD, ARM::VST4q32_UPD,
false,
true,
true, EvenDblSpc, 4, 2 ,
true},
491{ ARM::VST4q32oddPseudo, ARM::VST4q32,
false,
false,
false, OddDblSpc, 4, 2 ,
true},
492{ ARM::VST4q32oddPseudo_UPD, ARM::VST4q32_UPD,
false,
true,
true, OddDblSpc, 4, 2 ,
true},
493{ ARM::VST4q8Pseudo_UPD, ARM::VST4q8_UPD,
false,
true,
true, EvenDblSpc, 4, 8 ,
true},
494{ ARM::VST4q8oddPseudo, ARM::VST4q8,
false,
false,
false, OddDblSpc, 4, 8 ,
true},
495{ ARM::VST4q8oddPseudo_UPD, ARM::VST4q8_UPD,
false,
true,
true, OddDblSpc, 4, 8 ,
true}
503 static std::atomic<bool> TableChecked(
false);
504 if (!TableChecked.load(std::memory_order_relaxed)) {
506 TableChecked.store(
true, std::memory_order_relaxed);
522 if (RegSpc == SingleSpc || RegSpc == SingleLowSpc) {
523 D0 =
TRI->getSubReg(
Reg, ARM::dsub_0);
524 D1 =
TRI->getSubReg(
Reg, ARM::dsub_1);
525 D2 =
TRI->getSubReg(
Reg, ARM::dsub_2);
526 D3 =
TRI->getSubReg(
Reg, ARM::dsub_3);
527 }
else if (RegSpc == SingleHighQSpc) {
528 D0 =
TRI->getSubReg(
Reg, ARM::dsub_4);
529 D1 =
TRI->getSubReg(
Reg, ARM::dsub_5);
530 D2 =
TRI->getSubReg(
Reg, ARM::dsub_6);
531 D3 =
TRI->getSubReg(
Reg, ARM::dsub_7);
532 }
else if (RegSpc == SingleHighTSpc) {
533 D0 =
TRI->getSubReg(
Reg, ARM::dsub_3);
534 D1 =
TRI->getSubReg(
Reg, ARM::dsub_4);
535 D2 =
TRI->getSubReg(
Reg, ARM::dsub_5);
536 D3 =
TRI->getSubReg(
Reg, ARM::dsub_6);
537 }
else if (RegSpc == EvenDblSpc) {
538 D0 =
TRI->getSubReg(
Reg, ARM::dsub_0);
539 D1 =
TRI->getSubReg(
Reg, ARM::dsub_2);
540 D2 =
TRI->getSubReg(
Reg, ARM::dsub_4);
541 D3 =
TRI->getSubReg(
Reg, ARM::dsub_6);
543 assert(RegSpc == OddDblSpc &&
"unknown register spacing");
544 D0 =
TRI->getSubReg(
Reg, ARM::dsub_1);
545 D1 =
TRI->getSubReg(
Reg, ARM::dsub_3);
546 D2 =
TRI->getSubReg(
Reg, ARM::dsub_5);
547 D3 =
TRI->getSubReg(
Reg, ARM::dsub_7);
555 MachineBasicBlock &
MBB = *
MI.getParent();
559 assert(TableEntry && TableEntry->IsLoad &&
"NEONLdStTable lookup failed");
560 NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
561 unsigned NumRegs = TableEntry->NumRegs;
564 TII->get(TableEntry->RealOpc));
567 bool DstIsDead =
MI.getOperand(
OpIdx).isDead();
570 bool IsVLD2DUP = TableEntry->RealOpc == ARM::VLD2DUPd8x2 ||
571 TableEntry->RealOpc == ARM::VLD2DUPd16x2 ||
572 TableEntry->RealOpc == ARM::VLD2DUPd32x2 ||
573 TableEntry->RealOpc == ARM::VLD2DUPd8x2wb_fixed ||
574 TableEntry->RealOpc == ARM::VLD2DUPd16x2wb_fixed ||
575 TableEntry->RealOpc == ARM::VLD2DUPd32x2wb_fixed ||
576 TableEntry->RealOpc == ARM::VLD2DUPd8x2wb_register ||
577 TableEntry->RealOpc == ARM::VLD2DUPd16x2wb_register ||
578 TableEntry->RealOpc == ARM::VLD2DUPd32x2wb_register;
581 unsigned SubRegIndex;
582 if (RegSpc == EvenDblSpc) {
583 SubRegIndex = ARM::dsub_0;
585 assert(RegSpc == OddDblSpc &&
"Unexpected spacing!");
586 SubRegIndex = ARM::dsub_1;
588 Register SubReg =
TRI->getSubReg(DstReg, SubRegIndex);
589 MCRegister DstRegPair =
590 TRI->getMatchingSuperReg(SubReg, ARM::dsub_0, &ARM::DPairSpcRegClass);
593 MCRegister D0, D1, D2, D3;
596 if (NumRegs > 1 && TableEntry->copyAllListRegs)
598 if (NumRegs > 2 && TableEntry->copyAllListRegs)
600 if (NumRegs > 3 && TableEntry->copyAllListRegs)
604 if (TableEntry->isUpdating)
612 if (TableEntry->hasWritebackOperand) {
620 const MachineOperand &AM6Offset =
MI.getOperand(
OpIdx++);
621 if (TableEntry->RealOpc == ARM::VLD1d8Qwb_fixed ||
622 TableEntry->RealOpc == ARM::VLD1d16Qwb_fixed ||
623 TableEntry->RealOpc == ARM::VLD1d32Qwb_fixed ||
624 TableEntry->RealOpc == ARM::VLD1d64Qwb_fixed ||
625 TableEntry->RealOpc == ARM::VLD1d8Twb_fixed ||
626 TableEntry->RealOpc == ARM::VLD1d16Twb_fixed ||
627 TableEntry->RealOpc == ARM::VLD1d32Twb_fixed ||
628 TableEntry->RealOpc == ARM::VLD1d64Twb_fixed ||
629 TableEntry->RealOpc == ARM::VLD2DUPd8x2wb_fixed ||
630 TableEntry->RealOpc == ARM::VLD2DUPd16x2wb_fixed ||
631 TableEntry->RealOpc == ARM::VLD2DUPd32x2wb_fixed) {
633 "A fixed writing-back pseudo instruction provides an offset "
643 unsigned SrcOpIdx = 0;
644 if (RegSpc == EvenDblSpc || RegSpc == OddDblSpc || RegSpc == SingleLowSpc ||
645 RegSpc == SingleHighQSpc || RegSpc == SingleHighTSpc)
655 MachineOperand MO =
MI.getOperand(SrcOpIdx);
665 MI.eraseFromParent();
673 MachineBasicBlock &
MBB = *
MI.getParent();
677 assert(TableEntry && !TableEntry->IsLoad &&
"NEONLdStTable lookup failed");
678 NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
679 unsigned NumRegs = TableEntry->NumRegs;
682 TII->get(TableEntry->RealOpc));
684 if (TableEntry->isUpdating)
691 if (TableEntry->hasWritebackOperand) {
699 const MachineOperand &AM6Offset =
MI.getOperand(
OpIdx++);
700 if (TableEntry->RealOpc == ARM::VST1d8Qwb_fixed ||
701 TableEntry->RealOpc == ARM::VST1d16Qwb_fixed ||
702 TableEntry->RealOpc == ARM::VST1d32Qwb_fixed ||
703 TableEntry->RealOpc == ARM::VST1d64Qwb_fixed ||
704 TableEntry->RealOpc == ARM::VST1d8Twb_fixed ||
705 TableEntry->RealOpc == ARM::VST1d16Twb_fixed ||
706 TableEntry->RealOpc == ARM::VST1d32Twb_fixed ||
707 TableEntry->RealOpc == ARM::VST1d64Twb_fixed) {
709 "A fixed writing-back pseudo instruction provides an offset "
716 bool SrcIsKill =
MI.getOperand(
OpIdx).isKill();
717 bool SrcIsUndef =
MI.getOperand(
OpIdx).isUndef();
719 MCRegister D0, D1, D2, D3;
722 if (NumRegs > 1 && TableEntry->copyAllListRegs)
724 if (NumRegs > 2 && TableEntry->copyAllListRegs)
726 if (NumRegs > 3 && TableEntry->copyAllListRegs)
733 if (SrcIsKill && !SrcIsUndef)
735 else if (!SrcIsUndef)
736 MIB.
addReg(SrcReg, RegState::Implicit);
741 MI.eraseFromParent();
749 MachineBasicBlock &
MBB = *
MI.getParent();
753 assert(TableEntry &&
"NEONLdStTable lookup failed");
754 NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
755 unsigned NumRegs = TableEntry->NumRegs;
756 unsigned RegElts = TableEntry->RegElts;
759 TII->get(TableEntry->RealOpc));
763 unsigned Lane =
MI.getOperand(
MI.getDesc().getNumOperands() - 3).getImm();
766 assert(RegSpc != OddDblSpc &&
"unexpected register spacing for VLD/VST-lane");
767 if (RegSpc == EvenDblSpc && Lane >= RegElts) {
771 assert(Lane < RegElts &&
"out of range lane for VLD/VST-lane");
773 MCRegister D0, D1, D2, D3;
775 bool DstIsDead =
false;
776 if (TableEntry->IsLoad) {
777 DstIsDead =
MI.getOperand(
OpIdx).isDead();
778 DstReg =
MI.getOperand(
OpIdx++).getReg();
789 if (TableEntry->isUpdating)
796 if (TableEntry->hasWritebackOperand)
800 MachineOperand MO =
MI.getOperand(
OpIdx++);
801 if (!TableEntry->IsLoad)
826 if (TableEntry->IsLoad)
832 MI.eraseFromParent();
838 unsigned Opc,
bool IsExt) {
840 MachineBasicBlock &
MBB = *
MI.getParent();
849 MachineOperand VdSrc(
MI.getOperand(
OpIdx++));
853 bool SrcIsKill =
MI.getOperand(
OpIdx).isKill();
855 MCRegister D0, D1, D2, D3;
860 MachineOperand VmSrc(
MI.getOperand(
OpIdx++));
870 MI.eraseFromParent();
876 MachineBasicBlock &
MBB = *
MI.getParent();
878 MI.getOpcode() == ARM::MQQPRStore ||
MI.getOpcode() == ARM::MQQQQPRStore
881 MachineInstrBuilder MIB =
889 MIB.
add(
MI.getOperand(1));
891 MIB.
addReg(
TRI->getSubReg(SrcReg, ARM::dsub_0), Flags);
892 MIB.
addReg(
TRI->getSubReg(SrcReg, ARM::dsub_1), Flags);
893 MIB.
addReg(
TRI->getSubReg(SrcReg, ARM::dsub_2), Flags);
894 MIB.
addReg(
TRI->getSubReg(SrcReg, ARM::dsub_3), Flags);
895 if (
MI.getOpcode() == ARM::MQQQQPRStore ||
896 MI.getOpcode() == ARM::MQQQQPRLoad) {
897 MIB.
addReg(
TRI->getSubReg(SrcReg, ARM::dsub_4), Flags);
898 MIB.
addReg(
TRI->getSubReg(SrcReg, ARM::dsub_5), Flags);
899 MIB.
addReg(
TRI->getSubReg(SrcReg, ARM::dsub_6), Flags);
900 MIB.
addReg(
TRI->getSubReg(SrcReg, ARM::dsub_7), Flags);
903 if (NewOpc == ARM::VSTMDIA)
904 MIB.
addReg(SrcReg, RegState::Implicit);
908 MI.eraseFromParent();
957 unsigned TargetFlag) {
961 unsigned Imm = MO.
getImm();
962 switch (TargetFlag) {
964 Imm = (Imm >> 24) & 0xff;
967 Imm = (Imm >> 16) & 0xff;
970 Imm = (Imm >> 8) & 0xff;
976 Imm = (Imm >> 16) & 0xffff;
997void ARMExpandPseudo::ExpandTMOV32BitImm(MachineBasicBlock &
MBB,
1001 bool DstIsDead =
MI.getOperand(0).isDead();
1002 const MachineOperand &MO =
MI.getOperand(1);
1003 unsigned MIFlags =
MI.getFlags();
1012 unsigned PendingShift = 0;
1013 for (
unsigned Byte = 0;
Byte < 4; ++
Byte) {
1019 bool ZeroImm = Operand.
isImm() && Operand.
getImm() == 0;
1020 unsigned Op = PendingShift ? ARM::tADDi8 : ARM::tMOVi8;
1024 if (PendingShift && (!ZeroImm || Byte == 3)) {
1039 MachineInstrBuilder MIB =
1042 if (
Op == ARM::tADDi8)
1052 if (PendingShift || !ZeroImm)
1058 (--
MBBI)->getOperand(0).setIsDead(DstIsDead);
1060 MI.eraseFromParent();
1063void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &
MBB,
1065 MachineInstr &
MI = *
MBBI;
1066 unsigned Opcode =
MI.getOpcode();
1070 bool DstIsDead =
MI.getOperand(0).isDead();
1071 bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
1072 const MachineOperand &MO =
MI.getOperand(isCC ? 2 : 1);
1077 if (!STI->hasV6T2Ops() &&
1078 (Opcode == ARM::MOVi32imm || Opcode == ARM::MOVCCi32imm)) {
1082 assert (MO.
isImm() &&
"MOVi32imm w/ non-immediate source operand!");
1083 unsigned ImmVal = (unsigned)MO.
getImm();
1084 unsigned SOImmValV1 = 0, SOImmValV2 = 0;
1100 SOImmValV1 = ~(-SOImmValV1);
1103 unsigned MIFlags =
MI.getFlags();
1108 LO16.setMIFlags(MIFlags);
1109 HI16.setMIFlags(MIFlags);
1114 LO16.copyImplicitOps(
MI);
1115 HI16.copyImplicitOps(
MI);
1116 MI.eraseFromParent();
1120 unsigned LO16Opc = 0;
1121 unsigned HI16Opc = 0;
1122 unsigned MIFlags =
MI.getFlags();
1123 if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) {
1124 LO16Opc = ARM::t2MOVi16;
1125 HI16Opc = ARM::t2MOVTi16;
1127 LO16Opc = ARM::MOVi16;
1128 HI16Opc = ARM::MOVTi16;
1132 LO16.setMIFlags(MIFlags);
1135 LO16.addImm(Pred).addReg(PredReg);
1138 LO16.copyImplicitOps(
MI);
1142 if (!(HIOperand.isImm() && HIOperand.getImm() == 0)) {
1146 HI16.setMIFlags(MIFlags);
1147 HI16.add(HIOperand);
1149 HI16.addImm(Pred).addReg(PredReg);
1150 HI16.copyImplicitOps(
MI);
1153 LO16->getOperand(0).setIsDead(DstIsDead);
1156 if (RequiresBundling)
1159 MI.eraseFromParent();
1167 const std::initializer_list<unsigned> &Regs,
1171 if (!
Op.isReg() || !
Op.isUse())
1177 std::set_difference(Regs.begin(), Regs.end(), OpRegs.
begin(), OpRegs.
end(),
1178 std::back_inserter(ClearRegs));
1181void ARMExpandPseudo::CMSEClearGPRegs(
1183 const DebugLoc &
DL,
const SmallVectorImpl<unsigned> &ClearRegs,
1184 unsigned ClobberReg) {
1186 if (STI->hasV8_1MMainlineOps()) {
1188 MachineInstrBuilder CLRM =
1190 for (
unsigned R : ClearRegs)
1191 CLRM.
addReg(R, RegState::Define);
1192 CLRM.
addReg(ARM::APSR, RegState::Define);
1193 CLRM.
addReg(ARM::CPSR, RegState::Define | RegState::Implicit);
1197 for (
unsigned Reg : ClearRegs) {
1198 if (
Reg == ClobberReg)
1206 .
addImm(STI->hasDSP() ? 0xc00 : 0x800)
1225 if ((
Reg >= ARM::Q0 &&
Reg <= ARM::Q7) ||
1226 (
Reg >= ARM::D0 &&
Reg <= ARM::D15) ||
1227 (
Reg >= ARM::S0 &&
Reg <= ARM::S31))
1232 if (
Reg >= ARM::Q0 &&
Reg <= ARM::Q7) {
1233 int R =
Reg - ARM::Q0;
1234 ClearRegs.
reset(R * 4, (R + 1) * 4);
1235 }
else if (
Reg >= ARM::D0 &&
Reg <= ARM::D15) {
1236 int R =
Reg - ARM::D0;
1237 ClearRegs.
reset(R * 2, (R + 1) * 2);
1238 }
else if (
Reg >= ARM::S0 &&
Reg <= ARM::S31) {
1239 ClearRegs[
Reg - ARM::S0] =
false;
1246ARMExpandPseudo::CMSEClearFPRegs(MachineBasicBlock &
MBB,
1248 BitVector ClearRegs(16,
true);
1251 if (STI->hasV8_1MMainlineOps())
1252 return CMSEClearFPRegsV81(
MBB,
MBBI, ClearRegs);
1254 return CMSEClearFPRegsV8(
MBB,
MBBI, ClearRegs);
1260ARMExpandPseudo::CMSEClearFPRegsV8(MachineBasicBlock &
MBB,
1262 const BitVector &ClearRegs) {
1263 if (!STI->hasFPRegs())
1272 MachineBasicBlock *ClearBB, *DoneBB;
1274 ClearBB = DoneBB = &
MBB;
1291 for (
const MachineOperand &
Op : RetI.operands()) {
1295 if (
Reg == ARM::NoRegister ||
Reg == ARM::LR)
1317 .
addReg(ARM::CPSR, RegState::Kill);
1321 for (
unsigned D = 0;
D < 8;
D++) {
1323 if (ClearRegs[
D * 2 + 0] && ClearRegs[
D * 2 + 1]) {
1324 unsigned Reg = ARM::D0 +
D;
1331 if (ClearRegs[
D * 2 + 0]) {
1332 unsigned Reg = ARM::S0 +
D * 2;
1338 if (ClearRegs[
D * 2 + 1]) {
1339 unsigned Reg = ARM::S0 +
D * 2 + 1;
1369ARMExpandPseudo::CMSEClearFPRegsV81(MachineBasicBlock &
MBB,
1371 const BitVector &ClearRegs) {
1376 int Start = -1, End = -1;
1377 for (
int S = 0,
E = ClearRegs.
size(); S !=
E; ++S) {
1378 if (ClearRegs[S] && S == End + 1) {
1384 MachineInstrBuilder VSCCLRM =
1387 while (++Start <= End)
1388 VSCCLRM.
addReg(ARM::S0 + Start, RegState::Define);
1389 VSCCLRM.
addReg(ARM::VPR, RegState::Define);
1395 MachineInstrBuilder VSCCLRM =
1398 while (++Start <= End)
1399 VSCCLRM.
addReg(ARM::S0 + Start, RegState::Define);
1400 VSCCLRM.
addReg(ARM::VPR, RegState::Define);
1406void ARMExpandPseudo::CMSESaveClearFPRegs(
1408 const LivePhysRegs &LiveRegs, SmallVectorImpl<unsigned> &ScratchRegs) {
1409 if (STI->hasV8_1MMainlineOps())
1410 CMSESaveClearFPRegsV81(
MBB,
MBBI,
DL, LiveRegs);
1411 else if (STI->hasV8MMainlineOps())
1412 CMSESaveClearFPRegsV8(
MBB,
MBBI,
DL, LiveRegs, ScratchRegs);
1416void ARMExpandPseudo::CMSESaveClearFPRegsV8(
1418 const LivePhysRegs &LiveRegs, SmallVectorImpl<unsigned> &ScratchRegs) {
1422 unsigned SpareReg = ScratchRegs.
front();
1431 std::vector<std::tuple<unsigned, unsigned, unsigned>> ClearedFPRegs;
1432 std::vector<unsigned> NonclearedFPRegs;
1433 bool ReturnsFPReg =
false;
1434 for (
const MachineOperand &
Op :
MBBI->operands()) {
1435 if (
Op.isReg() &&
Op.isUse()) {
1441 if (ScratchRegs.
size() >= 2) {
1444 ClearedFPRegs.emplace_back(
Reg, SaveReg1, SaveReg2);
1448 .
addReg(SaveReg1, RegState::Define)
1449 .
addReg(SaveReg2, RegState::Define)
1453 NonclearedFPRegs.push_back(
Reg);
1456 if (ScratchRegs.
size() >= 1) {
1458 ClearedFPRegs.emplace_back(
Reg, SaveReg, 0);
1465 NonclearedFPRegs.push_back(
Reg);
1468 }
else if (
Op.isReg() &&
Op.isDef()) {
1472 ReturnsFPReg =
true;
1476 bool PassesFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty());
1478 if (PassesFPReg || ReturnsFPReg)
1479 assert(STI->hasFPRegs() &&
"Subtarget needs fpregs");
1505 if (ReturnsFPReg && !PassesFPReg) {
1506 bool S0Dead = !LiveRegs.contains(ARM::S0);
1515 MachineInstrBuilder VLSTM =
1530 for (
const auto &Regs : ClearedFPRegs) {
1531 unsigned Reg, SaveReg1, SaveReg2;
1532 std::tie(
Reg, SaveReg1, SaveReg2) = Regs;
1544 for (
unsigned Reg : NonclearedFPRegs) {
1554 MCRegister SReg0 =
TRI->getSubReg(
Reg, ARM::ssub_0);
1597void ARMExpandPseudo::CMSESaveClearFPRegsV81(MachineBasicBlock &
MBB,
1600 const LivePhysRegs &LiveRegs) {
1601 BitVector ClearRegs(32,
true);
1607 if (!DefFP && ClearRegs.
count() == ClearRegs.
size()) {
1615 MachineInstrBuilder VLSTM =
1630 MachineInstrBuilder VPUSH =
1634 for (
unsigned Reg = ARM::S16;
Reg <= ARM::S31; ++
Reg)
1638 (void)CMSEClearFPRegsV81(
MBB,
MBBI, ClearRegs);
1649void ARMExpandPseudo::CMSERestoreFPRegs(
1651 SmallVectorImpl<unsigned> &AvailableRegs) {
1652 if (STI->hasV8_1MMainlineOps())
1653 CMSERestoreFPRegsV81(
MBB,
MBBI,
DL, AvailableRegs);
1654 else if (STI->hasV8MMainlineOps())
1655 CMSERestoreFPRegsV8(
MBB,
MBBI,
DL, AvailableRegs);
1658void ARMExpandPseudo::CMSERestoreFPRegsV8(
1660 SmallVectorImpl<unsigned> &AvailableRegs) {
1663 unsigned ScratchReg = ARM::NoRegister;
1664 if (STI->fixCMSE_CVE_2021_35465())
1668 std::vector<std::tuple<unsigned, unsigned, unsigned>> ClearedFPRegs;
1669 std::vector<unsigned> NonclearedFPRegs;
1670 for (
const MachineOperand &
Op :
MBBI->operands()) {
1671 if (
Op.isReg() &&
Op.isDef()) {
1677 if (AvailableRegs.
size() >= 2) {
1680 ClearedFPRegs.emplace_back(
Reg, SaveReg1, SaveReg2);
1684 .
addReg(SaveReg1, RegState::Define)
1685 .
addReg(SaveReg2, RegState::Define)
1689 NonclearedFPRegs.push_back(
Reg);
1692 if (AvailableRegs.
size() >= 1) {
1694 ClearedFPRegs.emplace_back(
Reg, SaveReg, 0);
1701 NonclearedFPRegs.push_back(
Reg);
1707 bool returnsFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty());
1710 assert(STI->hasFPRegs() &&
"Subtarget needs fpregs");
1713 for (
unsigned Reg : NonclearedFPRegs) {
1730 MachineInstrBuilder VLLDM =
1737 if (STI->fixCMSE_CVE_2021_35465()) {
1738 auto Bundler = MIBundleBuilder(
MBB, VLLDM);
1741 .
addReg(ScratchReg, RegState::Define)
1757 if (STI->hasFPRegs())
1759 .
addReg(ARM::S0, RegState::Define)
1760 .
addReg(ARM::S0, RegState::Undef)
1770 for (
const auto &Regs : ClearedFPRegs) {
1771 unsigned Reg, SaveReg1, SaveReg2;
1772 std::tie(
Reg, SaveReg1, SaveReg2) = Regs;
1796 if ((
Reg >= ARM::Q0 &&
Reg <= ARM::Q7) ||
1797 (
Reg >= ARM::D0 &&
Reg <= ARM::D15) ||
1798 (
Reg >= ARM::S0 &&
Reg <= ARM::S31))
1804void ARMExpandPseudo::CMSERestoreFPRegsV81(
1806 SmallVectorImpl<unsigned> &AvailableRegs) {
1808 if (STI->fixCMSE_CVE_2021_35465()) {
1811 .
addReg(ARM::VPR, RegState::Define);
1835 MachineInstrBuilder VPOP =
1839 for (
unsigned Reg = ARM::S16;
Reg <= ARM::S31; ++
Reg)
1847bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &
MBB,
1849 unsigned LdrexOp,
unsigned StrexOp,
1852 bool IsThumb = STI->isThumb();
1854 MachineInstr &
MI = *
MBBI;
1856 const MachineOperand &Dest =
MI.getOperand(0);
1857 Register TempReg =
MI.getOperand(1).getReg();
1860 assert(!
MI.getOperand(2).isUndef() &&
"cannot handle undef");
1861 Register AddrReg =
MI.getOperand(2).getReg();
1862 Register DesiredReg =
MI.getOperand(3).getReg();
1866 assert(STI->hasV8MBaselineOps() &&
1867 "CMP_SWAP not expected to be custom expanded for Thumb1");
1868 assert((UxtOp == 0 || UxtOp == ARM::tUXTB || UxtOp == ARM::tUXTH) &&
1869 "ARMv8-M.baseline does not have t2UXTB/t2UXTH");
1871 "DesiredReg used for UXT op must be tGPR");
1880 MF->
insert(++LoadCmpBB->getIterator(), StoreBB);
1881 MF->
insert(++StoreBB->getIterator(), DoneBB);
1884 MachineInstrBuilder MIB =
1886 .
addReg(DesiredReg, RegState::Kill);
1897 MachineInstrBuilder MIB;
1900 if (LdrexOp == ARM::t2LDREX)
1904 unsigned CMPrr = IsThumb ? ARM::tCMPhir : ARM::CMPrr;
1909 unsigned Bcc = IsThumb ? ARM::tBcc : ARM::Bcc;
1913 .
addReg(ARM::CPSR, RegState::Kill);
1914 LoadCmpBB->addSuccessor(DoneBB);
1915 LoadCmpBB->addSuccessor(StoreBB);
1924 if (StrexOp == ARM::t2STREX)
1929 IsThumb ? (IsThumb1Only ? ARM::tCMPi8 : ARM::t2CMPri) :
ARM::CMPri;
1931 .
addReg(TempReg, RegState::Kill)
1937 .
addReg(ARM::CPSR, RegState::Kill);
1938 StoreBB->addSuccessor(LoadCmpBB);
1939 StoreBB->addSuccessor(DoneBB);
1947 MI.eraseFromParent();
1950 LivePhysRegs LiveRegs;
1955 StoreBB->clearLiveIns();
1957 LoadCmpBB->clearLiveIns();
1972 MIB.
addReg(RegLo, Flags);
1973 MIB.
addReg(RegHi, Flags);
1979bool ARMExpandPseudo::ExpandCMP_SWAP_64(MachineBasicBlock &
MBB,
1982 bool IsThumb = STI->isThumb();
1984 MachineInstr &
MI = *
MBBI;
1986 MachineOperand &Dest =
MI.getOperand(0);
1989 assert(!
MI.getOperand(1).isUndef() &&
"cannot handle undef");
1990 Register AddrAndTempReg =
MI.getOperand(1).getReg();
1991 Register AddrReg =
TRI->getSubReg(AddrAndTempReg, ARM::gsub_0);
1992 Register TempReg =
TRI->getSubReg(AddrAndTempReg, ARM::gsub_1);
1993 assert(
MI.getOperand(1).getReg() ==
MI.getOperand(2).getReg() &&
1994 "tied operands have different registers");
1995 Register DesiredReg =
MI.getOperand(3).getReg();
1996 MachineOperand
New =
MI.getOperand(4);
1997 New.setIsKill(
false);
2001 Register DesiredLo =
TRI->getSubReg(DesiredReg, ARM::gsub_0);
2002 Register DesiredHi =
TRI->getSubReg(DesiredReg, ARM::gsub_1);
2010 MF->
insert(++LoadCmpBB->getIterator(), StoreBB);
2011 MF->
insert(++StoreBB->getIterator(), DoneBB);
2018 unsigned LDREXD = IsThumb ? ARM::t2LDREXD : ARM::LDREXD;
2019 MachineInstrBuilder MIB;
2024 unsigned CMPrr = IsThumb ? ARM::tCMPhir : ARM::CMPrr;
2035 unsigned Bcc = IsThumb ? ARM::tBcc : ARM::Bcc;
2039 .
addReg(ARM::CPSR, RegState::Kill);
2040 LoadCmpBB->addSuccessor(DoneBB);
2041 LoadCmpBB->addSuccessor(StoreBB);
2047 unsigned STREXD = IsThumb ? ARM::t2STREXD : ARM::STREXD;
2053 unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
2055 .
addReg(TempReg, RegState::Kill)
2061 .
addReg(ARM::CPSR, RegState::Kill);
2062 StoreBB->addSuccessor(LoadCmpBB);
2063 StoreBB->addSuccessor(DoneBB);
2071 MI.eraseFromParent();
2074 LivePhysRegs LiveRegs;
2079 StoreBB->clearLiveIns();
2081 LoadCmpBB->clearLiveIns();
2096 for (
unsigned Reg = ARM::R4;
Reg < ARM::R8; ++
Reg) {
2108 for (
unsigned LoReg = ARM::R7, HiReg = ARM::R11; LoReg >= ARM::R4;
2110 if (JumpReg == LoReg)
2119 for (
unsigned Reg = ARM::R4;
Reg < ARM::R8; ++
Reg) {
2128 if (JumpReg >= ARM::R4 && JumpReg <= ARM::R7) {
2129 Register LoReg = JumpReg == ARM::R4 ? ARM::R5 : ARM::R4;
2142 for (
unsigned Reg = ARM::R4;
Reg < ARM::R12; ++
Reg) {
2157 for (
int R = 0; R < 4; ++R) {
2165 for (
int R = 0; R < 4; ++R)
2172 for (
unsigned Reg = ARM::R4;
Reg < ARM::R12; ++
Reg)
2177bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &
MBB,
2180 MachineInstr &
MI = *
MBBI;
2181 unsigned Opcode =
MI.getOpcode();
2189 if (DstReg ==
MI.getOperand(3).getReg()) {
2191 unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBITd : ARM::VBITq;
2193 .
add(
MI.getOperand(0))
2194 .
add(
MI.getOperand(3))
2195 .
add(
MI.getOperand(2))
2196 .
add(
MI.getOperand(1))
2198 .
add(
MI.getOperand(5));
2199 }
else if (DstReg ==
MI.getOperand(2).getReg()) {
2201 unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBIFd : ARM::VBIFq;
2203 .
add(
MI.getOperand(0))
2204 .
add(
MI.getOperand(2))
2205 .
add(
MI.getOperand(3))
2206 .
add(
MI.getOperand(1))
2208 .
add(
MI.getOperand(5));
2211 unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBSLd : ARM::VBSLq;
2212 if (DstReg ==
MI.getOperand(1).getReg()) {
2214 .
add(
MI.getOperand(0))
2215 .
add(
MI.getOperand(1))
2216 .
add(
MI.getOperand(2))
2217 .
add(
MI.getOperand(3))
2219 .
add(
MI.getOperand(5));
2222 unsigned MoveOpc = Opcode == ARM::VBSPd ? ARM::VORRd : ARM::VORRq;
2228 .
addReg(
MI.getOperand(1).getReg(), MO1Flags)
2229 .
addReg(
MI.getOperand(1).getReg(), MO1Flags)
2231 .
add(
MI.getOperand(5));
2233 .
add(
MI.getOperand(0))
2237 .
add(
MI.getOperand(2))
2238 .
add(
MI.getOperand(3))
2240 .
add(
MI.getOperand(5));
2243 MI.eraseFromParent();
2247 case ARM::CLEANUPRET:
2248 case ARM::CATCHRET: {
2249 unsigned RetOpcode = STI->isThumb() ? ARM::tBX_RET : ARM::BX_RET;
2252 MI.eraseFromParent();
2255 case ARM::TCRETURNdi:
2256 case ARM::TCRETURNri:
2257 case ARM::TCRETURNrinotr12: {
2259 if (
MBBI->getOpcode() == ARM::SEH_EpilogEnd)
2261 if (
MBBI->getOpcode() == ARM::SEH_Nop_Ret)
2264 "Can only insert epilog into returning blocks");
2265 unsigned RetOpcode =
MBBI->getOpcode();
2267 const ARMBaseInstrInfo &
TII = *
static_cast<const ARMBaseInstrInfo *
>(
2272 if (
MBBI->getOpcode() == ARM::SEH_EpilogEnd)
2274 if (
MBBI->getOpcode() == ARM::SEH_Nop_Ret)
2276 MachineOperand &JumpTarget =
MBBI->getOperand(0);
2279 if (RetOpcode == ARM::TCRETURNdi) {
2301 }
else if (RetOpcode == ARM::TCRETURNri ||
2302 RetOpcode == ARM::TCRETURNrinotr12) {
2304 STI->isThumb() ? ARM::tTAILJMPr
2305 : (STI->hasV4TOps() ? ARM::TAILJMPr : ARM::TAILJMPr4);
2311 auto NewMI = std::prev(
MBBI);
2312 for (
unsigned i = 2, e =
MBBI->getNumOperands(); i != e; ++i)
2313 NewMI->addOperand(
MBBI->getOperand(i));
2318 if (
MI.isCandidateForAdditionalCallInfo())
2319 MI.getMF()->moveAdditionalCallInfo(&
MI, &*NewMI);
2328 case ARM::tBXNS_RET: {
2334 MachineBasicBlock &AfterBB = CMSEClearFPRegs(
MBB,
MBBI);
2336 if (STI->hasV8_1MMainlineOps()) {
2339 TII->get(ARM::VLDR_FPCXTNS_post), ARM::SP)
2350 return !Op.isReg() || Op.getReg() != ARM::R12;
2354 *
MBBI, {ARM::R0, ARM::R1, ARM::R2, ARM::R3, ARM::R12}, ClearRegs);
2355 CMSEClearGPRegs(AfterBB, AfterBB.
end(),
MBBI->getDebugLoc(), ClearRegs,
2358 MachineInstrBuilder NewMI =
2360 TII->get(ARM::tBXNS))
2363 for (
const MachineOperand &
Op :
MI.operands())
2365 MI.eraseFromParent();
2368 case ARM::tBLXNS_CALL: {
2376 LivePhysRegs LiveRegs(*
TRI);
2377 LiveRegs.addLiveOuts(
MBB);
2379 LiveRegs.stepBackward(
MI);
2380 LiveRegs.stepBackward(*
MBBI);
2385 SmallVector<unsigned, 16> ClearRegs;
2387 {ARM::R0, ARM::R1, ARM::R2, ARM::R3, ARM::R4,
2388 ARM::R5, ARM::R6, ARM::R7, ARM::R8, ARM::R9,
2389 ARM::R10, ARM::R11, ARM::R12},
2391 auto OriginalClearRegs = ClearRegs;
2395 unsigned ScratchReg = ClearRegs.
front();
2413 .
addReg(ARM::CPSR, RegState::Define)
2419 CMSESaveClearFPRegs(
MBB,
MBBI,
DL, LiveRegs,
2421 CMSEClearGPRegs(
MBB,
MBBI,
DL, ClearRegs, JumpReg);
2423 const MachineInstrBuilder NewCall =
2426 .
addReg(JumpReg, RegState::Kill);
2430 if (
MI.isCandidateForAdditionalCallInfo())
2431 MI.getMF()->moveAdditionalCallInfo(&
MI, NewCall.
getInstr());
2433 CMSERestoreFPRegs(
MBB,
MBBI,
DL, OriginalClearRegs);
2437 MI.eraseFromParent();
2442 case ARM::VMOVDcc: {
2443 unsigned newOpc = Opcode != ARM::VMOVDcc ? ARM::VMOVS : ARM::VMOVD;
2445 MI.getOperand(1).getReg())
2446 .
add(
MI.getOperand(2))
2448 .
add(
MI.getOperand(4))
2451 MI.eraseFromParent();
2458 MI.getOperand(1).getReg())
2459 .
add(
MI.getOperand(2))
2461 .
add(
MI.getOperand(4))
2465 MI.eraseFromParent();
2468 case ARM::MOVCCsi: {
2470 (
MI.getOperand(1).getReg()))
2471 .
add(
MI.getOperand(2))
2474 .
add(
MI.getOperand(5))
2478 MI.eraseFromParent();
2481 case ARM::MOVCCsr: {
2483 (
MI.getOperand(1).getReg()))
2484 .
add(
MI.getOperand(2))
2485 .
add(
MI.getOperand(3))
2488 .
add(
MI.getOperand(6))
2492 MI.eraseFromParent();
2495 case ARM::t2MOVCCi16:
2496 case ARM::MOVCCi16: {
2497 unsigned NewOpc = AFI->
isThumbFunction() ? ARM::t2MOVi16 : ARM::MOVi16;
2499 MI.getOperand(1).getReg())
2502 .
add(
MI.getOperand(4))
2504 MI.eraseFromParent();
2511 MI.getOperand(1).getReg())
2514 .
add(
MI.getOperand(4))
2518 MI.eraseFromParent();
2525 MI.getOperand(1).getReg())
2528 .
add(
MI.getOperand(4))
2532 MI.eraseFromParent();
2535 case ARM::t2MOVCClsl:
2536 case ARM::t2MOVCClsr:
2537 case ARM::t2MOVCCasr:
2538 case ARM::t2MOVCCror: {
2541 case ARM::t2MOVCClsl: NewOpc = ARM::t2LSLri;
break;
2542 case ARM::t2MOVCClsr: NewOpc = ARM::t2LSRri;
break;
2543 case ARM::t2MOVCCasr: NewOpc = ARM::t2ASRri;
break;
2544 case ARM::t2MOVCCror: NewOpc = ARM::t2RORri;
break;
2548 MI.getOperand(1).getReg())
2549 .
add(
MI.getOperand(2))
2552 .
add(
MI.getOperand(5))
2555 MI.eraseFromParent();
2558 case ARM::Int_eh_sjlj_dispatchsetup: {
2559 MachineFunction &MF = *
MI.getParent()->getParent();
2568 "base pointer without frame pointer?");
2582 if (RI.hasStackRealignment(MF)) {
2588 "The BIC instruction cannot encode "
2589 "immediates larger than 256 with all lower "
2592 ARM::t2BICri : ARM::BICri;
2594 .
addReg(ARM::R6, RegState::Kill)
2600 MI.eraseFromParent();
2608 MI.getOperand(0).getReg())
2609 .
add(
MI.getOperand(1))
2613 .
addReg(ARM::CPSR, RegState::Define);
2614 MI.eraseFromParent();
2620 MI.getOperand(0).getReg())
2621 .
add(
MI.getOperand(1))
2626 MI.eraseFromParent();
2631 const bool Thumb = Opcode == ARM::tTPsoft;
2633 MachineInstrBuilder MIB;
2635 if (STI->genLongCalls()) {
2638 MachineConstantPoolValue *CPV =
2640 "__aeabi_read_tp", PCLabelID, 0);
2644 TII->get(Thumb ? ARM::tLDRpci : ARM::LDRi12),
Reg)
2658 TII->get(Thumb ? ARM::tBL : ARM::BL));
2667 if (
MI.isCandidateForAdditionalCallInfo())
2669 MI.eraseFromParent();
2672 case ARM::tLDRpci_pic:
2673 case ARM::t2LDRpci_pic: {
2674 unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
2675 ? ARM::tLDRpci :
ARM::t2LDRpci;
2677 bool DstIsDead =
MI.getOperand(0).isDead();
2679 .
add(
MI.getOperand(1))
2686 .
add(
MI.getOperand(2))
2688 MI.eraseFromParent();
2692 case ARM::LDRLIT_ga_abs:
2693 case ARM::LDRLIT_ga_pcrel:
2694 case ARM::LDRLIT_ga_pcrel_ldr:
2695 case ARM::tLDRLIT_ga_abs:
2696 case ARM::t2LDRLIT_ga_pcrel:
2697 case ARM::tLDRLIT_ga_pcrel: {
2699 bool DstIsDead =
MI.getOperand(0).isDead();
2700 const MachineOperand &MO1 =
MI.getOperand(1);
2702 const GlobalValue *GV = MO1.
getGlobal();
2703 bool IsARM = Opcode != ARM::tLDRLIT_ga_pcrel &&
2704 Opcode != ARM::tLDRLIT_ga_abs &&
2705 Opcode != ARM::t2LDRLIT_ga_pcrel;
2707 Opcode != ARM::LDRLIT_ga_abs && Opcode != ARM::tLDRLIT_ga_abs;
2708 unsigned LDRLITOpc = IsARM ? ARM::LDRi12 : ARM::tLDRpci;
2709 if (Opcode == ARM::t2LDRLIT_ga_pcrel)
2710 LDRLITOpc = ARM::t2LDRpci;
2711 unsigned PICAddOpc =
2713 ? (Opcode == ARM::LDRLIT_ga_pcrel_ldr ? ARM::PICLDR : ARM::PICADD)
2718 unsigned ARMPCLabelIndex = 0;
2719 MachineConstantPoolValue *CPV;
2722 unsigned PCAdj = IsARM ? 8 : 4;
2733 MachineInstrBuilder MIB =
2741 MachineInstrBuilder MIB =
2745 .
addImm(ARMPCLabelIndex);
2751 MI.eraseFromParent();
2754 case ARM::MOV_ga_pcrel:
2755 case ARM::MOV_ga_pcrel_ldr:
2756 case ARM::t2MOV_ga_pcrel: {
2760 bool DstIsDead =
MI.getOperand(0).isDead();
2761 const MachineOperand &MO1 =
MI.getOperand(1);
2762 const GlobalValue *GV = MO1.
getGlobal();
2764 bool isARM = Opcode != ARM::t2MOV_ga_pcrel;
2765 unsigned LO16Opc = isARM ? ARM::MOVi16_ga_pcrel : ARM::t2MOVi16_ga_pcrel;
2766 unsigned HI16Opc = isARM ? ARM::MOVTi16_ga_pcrel :ARM::t2MOVTi16_ga_pcrel;
2769 unsigned PICAddOpc = isARM
2770 ? (Opcode == ARM::MOV_ga_pcrel_ldr ? ARM::PICLDR : ARM::PICADD)
2784 TII->get(PICAddOpc))
2789 if (Opcode == ARM::MOV_ga_pcrel_ldr)
2793 MI.eraseFromParent();
2797 case ARM::MOVi32imm:
2798 case ARM::MOVCCi32imm:
2799 case ARM::t2MOVi32imm:
2800 case ARM::t2MOVCCi32imm:
2804 case ARM::tMOVi32imm:
2805 ExpandTMOV32BitImm(
MBB,
MBBI);
2808 case ARM::tLEApcrelJT:
2810 if (
MI.getMF()->getJumpTableInfo()->getEntryKind() ==
2815 assert(STI->isThumb() &&
"Non-inline jump tables expected only in thumb");
2816 ExpandTMOV32BitImm(
MBB,
MBBI);
2819 case ARM::SUBS_PC_LR: {
2822 .
add(
MI.getOperand(0))
2823 .
add(
MI.getOperand(1))
2824 .
add(
MI.getOperand(2))
2825 .
addReg(ARM::CPSR, RegState::Undef)
2827 MI.eraseFromParent();
2830 case ARM::VLDMQIA: {
2831 unsigned NewOpc = ARM::VLDMDIA;
2832 MachineInstrBuilder MIB =
2837 bool DstIsDead =
MI.getOperand(
OpIdx).isDead();
2848 Register D0 =
TRI->getSubReg(DstReg, ARM::dsub_0);
2849 Register D1 =
TRI->getSubReg(DstReg, ARM::dsub_1);
2857 MI.eraseFromParent();
2861 case ARM::VSTMQIA: {
2862 unsigned NewOpc = ARM::VSTMDIA;
2863 MachineInstrBuilder MIB =
2868 bool SrcIsKill =
MI.getOperand(
OpIdx).isKill();
2872 MachineOperand Dst(
MI.getOperand(
OpIdx++));
2880 Register D0 =
TRI->getSubReg(SrcReg, ARM::dsub_0);
2881 Register D1 =
TRI->getSubReg(SrcReg, ARM::dsub_1);
2890 MI.eraseFromParent();
2894 case ARM::VLD2q8Pseudo:
2895 case ARM::VLD2q16Pseudo:
2896 case ARM::VLD2q32Pseudo:
2897 case ARM::VLD2q8PseudoWB_fixed:
2898 case ARM::VLD2q16PseudoWB_fixed:
2899 case ARM::VLD2q32PseudoWB_fixed:
2900 case ARM::VLD2q8PseudoWB_register:
2901 case ARM::VLD2q16PseudoWB_register:
2902 case ARM::VLD2q32PseudoWB_register:
2903 case ARM::VLD3d8Pseudo:
2904 case ARM::VLD3d16Pseudo:
2905 case ARM::VLD3d32Pseudo:
2906 case ARM::VLD1d8TPseudo:
2907 case ARM::VLD1d8TPseudoWB_fixed:
2908 case ARM::VLD1d8TPseudoWB_register:
2909 case ARM::VLD1d16TPseudo:
2910 case ARM::VLD1d16TPseudoWB_fixed:
2911 case ARM::VLD1d16TPseudoWB_register:
2912 case ARM::VLD1d32TPseudo:
2913 case ARM::VLD1d32TPseudoWB_fixed:
2914 case ARM::VLD1d32TPseudoWB_register:
2915 case ARM::VLD1d64TPseudo:
2916 case ARM::VLD1d64TPseudoWB_fixed:
2917 case ARM::VLD1d64TPseudoWB_register:
2918 case ARM::VLD3d8Pseudo_UPD:
2919 case ARM::VLD3d16Pseudo_UPD:
2920 case ARM::VLD3d32Pseudo_UPD:
2921 case ARM::VLD3q8Pseudo_UPD:
2922 case ARM::VLD3q16Pseudo_UPD:
2923 case ARM::VLD3q32Pseudo_UPD:
2924 case ARM::VLD3q8oddPseudo:
2925 case ARM::VLD3q16oddPseudo:
2926 case ARM::VLD3q32oddPseudo:
2927 case ARM::VLD3q8oddPseudo_UPD:
2928 case ARM::VLD3q16oddPseudo_UPD:
2929 case ARM::VLD3q32oddPseudo_UPD:
2930 case ARM::VLD4d8Pseudo:
2931 case ARM::VLD4d16Pseudo:
2932 case ARM::VLD4d32Pseudo:
2933 case ARM::VLD1d8QPseudo:
2934 case ARM::VLD1d8QPseudoWB_fixed:
2935 case ARM::VLD1d8QPseudoWB_register:
2936 case ARM::VLD1d16QPseudo:
2937 case ARM::VLD1d16QPseudoWB_fixed:
2938 case ARM::VLD1d16QPseudoWB_register:
2939 case ARM::VLD1d32QPseudo:
2940 case ARM::VLD1d32QPseudoWB_fixed:
2941 case ARM::VLD1d32QPseudoWB_register:
2942 case ARM::VLD1d64QPseudo:
2943 case ARM::VLD1d64QPseudoWB_fixed:
2944 case ARM::VLD1d64QPseudoWB_register:
2945 case ARM::VLD1q8HighQPseudo:
2946 case ARM::VLD1q8HighQPseudo_UPD:
2947 case ARM::VLD1q8LowQPseudo_UPD:
2948 case ARM::VLD1q8HighTPseudo:
2949 case ARM::VLD1q8HighTPseudo_UPD:
2950 case ARM::VLD1q8LowTPseudo_UPD:
2951 case ARM::VLD1q16HighQPseudo:
2952 case ARM::VLD1q16HighQPseudo_UPD:
2953 case ARM::VLD1q16LowQPseudo_UPD:
2954 case ARM::VLD1q16HighTPseudo:
2955 case ARM::VLD1q16HighTPseudo_UPD:
2956 case ARM::VLD1q16LowTPseudo_UPD:
2957 case ARM::VLD1q32HighQPseudo:
2958 case ARM::VLD1q32HighQPseudo_UPD:
2959 case ARM::VLD1q32LowQPseudo_UPD:
2960 case ARM::VLD1q32HighTPseudo:
2961 case ARM::VLD1q32HighTPseudo_UPD:
2962 case ARM::VLD1q32LowTPseudo_UPD:
2963 case ARM::VLD1q64HighQPseudo:
2964 case ARM::VLD1q64HighQPseudo_UPD:
2965 case ARM::VLD1q64LowQPseudo_UPD:
2966 case ARM::VLD1q64HighTPseudo:
2967 case ARM::VLD1q64HighTPseudo_UPD:
2968 case ARM::VLD1q64LowTPseudo_UPD:
2969 case ARM::VLD4d8Pseudo_UPD:
2970 case ARM::VLD4d16Pseudo_UPD:
2971 case ARM::VLD4d32Pseudo_UPD:
2972 case ARM::VLD4q8Pseudo_UPD:
2973 case ARM::VLD4q16Pseudo_UPD:
2974 case ARM::VLD4q32Pseudo_UPD:
2975 case ARM::VLD4q8oddPseudo:
2976 case ARM::VLD4q16oddPseudo:
2977 case ARM::VLD4q32oddPseudo:
2978 case ARM::VLD4q8oddPseudo_UPD:
2979 case ARM::VLD4q16oddPseudo_UPD:
2980 case ARM::VLD4q32oddPseudo_UPD:
2981 case ARM::VLD3DUPd8Pseudo:
2982 case ARM::VLD3DUPd16Pseudo:
2983 case ARM::VLD3DUPd32Pseudo:
2984 case ARM::VLD3DUPd8Pseudo_UPD:
2985 case ARM::VLD3DUPd16Pseudo_UPD:
2986 case ARM::VLD3DUPd32Pseudo_UPD:
2987 case ARM::VLD4DUPd8Pseudo:
2988 case ARM::VLD4DUPd16Pseudo:
2989 case ARM::VLD4DUPd32Pseudo:
2990 case ARM::VLD4DUPd8Pseudo_UPD:
2991 case ARM::VLD4DUPd16Pseudo_UPD:
2992 case ARM::VLD4DUPd32Pseudo_UPD:
2993 case ARM::VLD2DUPq8EvenPseudo:
2994 case ARM::VLD2DUPq8OddPseudo:
2995 case ARM::VLD2DUPq16EvenPseudo:
2996 case ARM::VLD2DUPq16OddPseudo:
2997 case ARM::VLD2DUPq32EvenPseudo:
2998 case ARM::VLD2DUPq32OddPseudo:
2999 case ARM::VLD2DUPq8OddPseudoWB_fixed:
3000 case ARM::VLD2DUPq8OddPseudoWB_register:
3001 case ARM::VLD2DUPq16OddPseudoWB_fixed:
3002 case ARM::VLD2DUPq16OddPseudoWB_register:
3003 case ARM::VLD2DUPq32OddPseudoWB_fixed:
3004 case ARM::VLD2DUPq32OddPseudoWB_register:
3005 case ARM::VLD3DUPq8EvenPseudo:
3006 case ARM::VLD3DUPq8OddPseudo:
3007 case ARM::VLD3DUPq16EvenPseudo:
3008 case ARM::VLD3DUPq16OddPseudo:
3009 case ARM::VLD3DUPq32EvenPseudo:
3010 case ARM::VLD3DUPq32OddPseudo:
3011 case ARM::VLD3DUPq8OddPseudo_UPD:
3012 case ARM::VLD3DUPq16OddPseudo_UPD:
3013 case ARM::VLD3DUPq32OddPseudo_UPD:
3014 case ARM::VLD4DUPq8EvenPseudo:
3015 case ARM::VLD4DUPq8OddPseudo:
3016 case ARM::VLD4DUPq16EvenPseudo:
3017 case ARM::VLD4DUPq16OddPseudo:
3018 case ARM::VLD4DUPq32EvenPseudo:
3019 case ARM::VLD4DUPq32OddPseudo:
3020 case ARM::VLD4DUPq8OddPseudo_UPD:
3021 case ARM::VLD4DUPq16OddPseudo_UPD:
3022 case ARM::VLD4DUPq32OddPseudo_UPD:
3026 case ARM::VST2q8Pseudo:
3027 case ARM::VST2q16Pseudo:
3028 case ARM::VST2q32Pseudo:
3029 case ARM::VST2q8PseudoWB_fixed:
3030 case ARM::VST2q16PseudoWB_fixed:
3031 case ARM::VST2q32PseudoWB_fixed:
3032 case ARM::VST2q8PseudoWB_register:
3033 case ARM::VST2q16PseudoWB_register:
3034 case ARM::VST2q32PseudoWB_register:
3035 case ARM::VST3d8Pseudo:
3036 case ARM::VST3d16Pseudo:
3037 case ARM::VST3d32Pseudo:
3038 case ARM::VST1d8TPseudo:
3039 case ARM::VST1d8TPseudoWB_fixed:
3040 case ARM::VST1d8TPseudoWB_register:
3041 case ARM::VST1d16TPseudo:
3042 case ARM::VST1d16TPseudoWB_fixed:
3043 case ARM::VST1d16TPseudoWB_register:
3044 case ARM::VST1d32TPseudo:
3045 case ARM::VST1d32TPseudoWB_fixed:
3046 case ARM::VST1d32TPseudoWB_register:
3047 case ARM::VST1d64TPseudo:
3048 case ARM::VST1d64TPseudoWB_fixed:
3049 case ARM::VST1d64TPseudoWB_register:
3050 case ARM::VST3d8Pseudo_UPD:
3051 case ARM::VST3d16Pseudo_UPD:
3052 case ARM::VST3d32Pseudo_UPD:
3053 case ARM::VST3q8Pseudo_UPD:
3054 case ARM::VST3q16Pseudo_UPD:
3055 case ARM::VST3q32Pseudo_UPD:
3056 case ARM::VST3q8oddPseudo:
3057 case ARM::VST3q16oddPseudo:
3058 case ARM::VST3q32oddPseudo:
3059 case ARM::VST3q8oddPseudo_UPD:
3060 case ARM::VST3q16oddPseudo_UPD:
3061 case ARM::VST3q32oddPseudo_UPD:
3062 case ARM::VST4d8Pseudo:
3063 case ARM::VST4d16Pseudo:
3064 case ARM::VST4d32Pseudo:
3065 case ARM::VST1d8QPseudo:
3066 case ARM::VST1d8QPseudoWB_fixed:
3067 case ARM::VST1d8QPseudoWB_register:
3068 case ARM::VST1d16QPseudo:
3069 case ARM::VST1d16QPseudoWB_fixed:
3070 case ARM::VST1d16QPseudoWB_register:
3071 case ARM::VST1d32QPseudo:
3072 case ARM::VST1d32QPseudoWB_fixed:
3073 case ARM::VST1d32QPseudoWB_register:
3074 case ARM::VST1d64QPseudo:
3075 case ARM::VST1d64QPseudoWB_fixed:
3076 case ARM::VST1d64QPseudoWB_register:
3077 case ARM::VST4d8Pseudo_UPD:
3078 case ARM::VST4d16Pseudo_UPD:
3079 case ARM::VST4d32Pseudo_UPD:
3080 case ARM::VST1q8HighQPseudo:
3081 case ARM::VST1q8LowQPseudo_UPD:
3082 case ARM::VST1q8HighTPseudo:
3083 case ARM::VST1q8LowTPseudo_UPD:
3084 case ARM::VST1q16HighQPseudo:
3085 case ARM::VST1q16LowQPseudo_UPD:
3086 case ARM::VST1q16HighTPseudo:
3087 case ARM::VST1q16LowTPseudo_UPD:
3088 case ARM::VST1q32HighQPseudo:
3089 case ARM::VST1q32LowQPseudo_UPD:
3090 case ARM::VST1q32HighTPseudo:
3091 case ARM::VST1q32LowTPseudo_UPD:
3092 case ARM::VST1q64HighQPseudo:
3093 case ARM::VST1q64LowQPseudo_UPD:
3094 case ARM::VST1q64HighTPseudo:
3095 case ARM::VST1q64LowTPseudo_UPD:
3096 case ARM::VST1q8HighTPseudo_UPD:
3097 case ARM::VST1q16HighTPseudo_UPD:
3098 case ARM::VST1q32HighTPseudo_UPD:
3099 case ARM::VST1q64HighTPseudo_UPD:
3100 case ARM::VST1q8HighQPseudo_UPD:
3101 case ARM::VST1q16HighQPseudo_UPD:
3102 case ARM::VST1q32HighQPseudo_UPD:
3103 case ARM::VST1q64HighQPseudo_UPD:
3104 case ARM::VST4q8Pseudo_UPD:
3105 case ARM::VST4q16Pseudo_UPD:
3106 case ARM::VST4q32Pseudo_UPD:
3107 case ARM::VST4q8oddPseudo:
3108 case ARM::VST4q16oddPseudo:
3109 case ARM::VST4q32oddPseudo:
3110 case ARM::VST4q8oddPseudo_UPD:
3111 case ARM::VST4q16oddPseudo_UPD:
3112 case ARM::VST4q32oddPseudo_UPD:
3116 case ARM::VLD1LNq8Pseudo:
3117 case ARM::VLD1LNq16Pseudo:
3118 case ARM::VLD1LNq32Pseudo:
3119 case ARM::VLD1LNq8Pseudo_UPD:
3120 case ARM::VLD1LNq16Pseudo_UPD:
3121 case ARM::VLD1LNq32Pseudo_UPD:
3122 case ARM::VLD2LNd8Pseudo:
3123 case ARM::VLD2LNd16Pseudo:
3124 case ARM::VLD2LNd32Pseudo:
3125 case ARM::VLD2LNq16Pseudo:
3126 case ARM::VLD2LNq32Pseudo:
3127 case ARM::VLD2LNd8Pseudo_UPD:
3128 case ARM::VLD2LNd16Pseudo_UPD:
3129 case ARM::VLD2LNd32Pseudo_UPD:
3130 case ARM::VLD2LNq16Pseudo_UPD:
3131 case ARM::VLD2LNq32Pseudo_UPD:
3132 case ARM::VLD3LNd8Pseudo:
3133 case ARM::VLD3LNd16Pseudo:
3134 case ARM::VLD3LNd32Pseudo:
3135 case ARM::VLD3LNq16Pseudo:
3136 case ARM::VLD3LNq32Pseudo:
3137 case ARM::VLD3LNd8Pseudo_UPD:
3138 case ARM::VLD3LNd16Pseudo_UPD:
3139 case ARM::VLD3LNd32Pseudo_UPD:
3140 case ARM::VLD3LNq16Pseudo_UPD:
3141 case ARM::VLD3LNq32Pseudo_UPD:
3142 case ARM::VLD4LNd8Pseudo:
3143 case ARM::VLD4LNd16Pseudo:
3144 case ARM::VLD4LNd32Pseudo:
3145 case ARM::VLD4LNq16Pseudo:
3146 case ARM::VLD4LNq32Pseudo:
3147 case ARM::VLD4LNd8Pseudo_UPD:
3148 case ARM::VLD4LNd16Pseudo_UPD:
3149 case ARM::VLD4LNd32Pseudo_UPD:
3150 case ARM::VLD4LNq16Pseudo_UPD:
3151 case ARM::VLD4LNq32Pseudo_UPD:
3152 case ARM::VST1LNq8Pseudo:
3153 case ARM::VST1LNq16Pseudo:
3154 case ARM::VST1LNq32Pseudo:
3155 case ARM::VST1LNq8Pseudo_UPD:
3156 case ARM::VST1LNq16Pseudo_UPD:
3157 case ARM::VST1LNq32Pseudo_UPD:
3158 case ARM::VST2LNd8Pseudo:
3159 case ARM::VST2LNd16Pseudo:
3160 case ARM::VST2LNd32Pseudo:
3161 case ARM::VST2LNq16Pseudo:
3162 case ARM::VST2LNq32Pseudo:
3163 case ARM::VST2LNd8Pseudo_UPD:
3164 case ARM::VST2LNd16Pseudo_UPD:
3165 case ARM::VST2LNd32Pseudo_UPD:
3166 case ARM::VST2LNq16Pseudo_UPD:
3167 case ARM::VST2LNq32Pseudo_UPD:
3168 case ARM::VST3LNd8Pseudo:
3169 case ARM::VST3LNd16Pseudo:
3170 case ARM::VST3LNd32Pseudo:
3171 case ARM::VST3LNq16Pseudo:
3172 case ARM::VST3LNq32Pseudo:
3173 case ARM::VST3LNd8Pseudo_UPD:
3174 case ARM::VST3LNd16Pseudo_UPD:
3175 case ARM::VST3LNd32Pseudo_UPD:
3176 case ARM::VST3LNq16Pseudo_UPD:
3177 case ARM::VST3LNq32Pseudo_UPD:
3178 case ARM::VST4LNd8Pseudo:
3179 case ARM::VST4LNd16Pseudo:
3180 case ARM::VST4LNd32Pseudo:
3181 case ARM::VST4LNq16Pseudo:
3182 case ARM::VST4LNq32Pseudo:
3183 case ARM::VST4LNd8Pseudo_UPD:
3184 case ARM::VST4LNd16Pseudo_UPD:
3185 case ARM::VST4LNd32Pseudo_UPD:
3186 case ARM::VST4LNq16Pseudo_UPD:
3187 case ARM::VST4LNq32Pseudo_UPD:
3191 case ARM::VTBL3Pseudo: ExpandVTBL(
MBBI, ARM::VTBL3,
false);
return true;
3192 case ARM::VTBL4Pseudo: ExpandVTBL(
MBBI, ARM::VTBL4,
false);
return true;
3193 case ARM::VTBX3Pseudo: ExpandVTBL(
MBBI, ARM::VTBX3,
true);
return true;
3194 case ARM::VTBX4Pseudo: ExpandVTBL(
MBBI, ARM::VTBX4,
true);
return true;
3196 case ARM::MQQPRLoad:
3197 case ARM::MQQPRStore:
3198 case ARM::MQQQQPRLoad:
3199 case ARM::MQQQQPRStore:
3200 ExpandMQQPRLoadStore(
MBBI);
3203 case ARM::tCMP_SWAP_8:
3205 return ExpandCMP_SWAP(
MBB,
MBBI, ARM::t2LDREXB, ARM::t2STREXB, ARM::tUXTB,
3207 case ARM::tCMP_SWAP_16:
3209 return ExpandCMP_SWAP(
MBB,
MBBI, ARM::t2LDREXH, ARM::t2STREXH, ARM::tUXTH,
3211 case ARM::tCMP_SWAP_32:
3213 return ExpandCMP_SWAP(
MBB,
MBBI, ARM::t2LDREX, ARM::t2STREX, 0, NextMBBI);
3215 case ARM::CMP_SWAP_8:
3217 return ExpandCMP_SWAP(
MBB,
MBBI, ARM::LDREXB, ARM::STREXB, ARM::UXTB,
3219 case ARM::CMP_SWAP_16:
3221 return ExpandCMP_SWAP(
MBB,
MBBI, ARM::LDREXH, ARM::STREXH, ARM::UXTH,
3223 case ARM::CMP_SWAP_32:
3225 return ExpandCMP_SWAP(
MBB,
MBBI, ARM::LDREX, ARM::STREX, 0, NextMBBI);
3227 case ARM::CMP_SWAP_64:
3228 return ExpandCMP_SWAP_64(
MBB,
MBBI, NextMBBI);
3230 case ARM::tBL_PUSHLR:
3231 case ARM::BL_PUSHLR: {
3232 const bool Thumb = Opcode == ARM::tBL_PUSHLR;
3234 assert(
Reg == ARM::LR &&
"expect LR register!");
3235 MachineInstrBuilder MIB;
3247 .
addReg(ARM::SP, RegState::Define)
3258 MI.eraseFromParent();
3261 case ARM::t2CALL_BTI: {
3262 MachineFunction &MF = *
MI.getMF();
3263 MachineInstrBuilder MIB =
3266 for (
unsigned i = 0; i <
MI.getNumOperands(); ++i)
3267 MIB.
add(
MI.getOperand(i));
3268 if (
MI.isCandidateForAdditionalCallInfo())
3270 MIBundleBuilder Bundler(
MBB,
MI);
3271 Bundler.append(MIB);
3272 Bundler.append(
BuildMI(MF,
MI.getDebugLoc(),
TII->get(ARM::t2BTI)));
3274 MI.eraseFromParent();
3278 case ARM::STOREDUAL: {
3279 Register PairReg =
MI.getOperand(0).getReg();
3281 MachineInstrBuilder MIB =
3283 TII->get(Opcode == ARM::LOADDUAL ? ARM::LDRD : ARM::STRD))
3284 .
addReg(
TRI->getSubReg(PairReg, ARM::gsub_0),
3286 .
addReg(
TRI->getSubReg(PairReg, ARM::gsub_1),
3292 MI.eraseFromParent();
3298bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &
MBB) {
3311bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
3315 AFI = MF.
getInfo<ARMFunctionInfo>();
3317 LLVM_DEBUG(
dbgs() <<
"********** ARM EXPAND PSEUDO INSTRUCTIONS **********\n"
3318 <<
"********** Function: " << MF.
getName() <<
'\n');
3321 for (MachineBasicBlock &
MBB : MF)
3324 MF.verify(
this,
"After expanding ARM pseudo instructions.");
3326 LLVM_DEBUG(
dbgs() <<
"***************************************************\n");
3333 return new ARMExpandPseudo();
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static bool determineFPRegsToClear(const MachineInstr &MI, BitVector &ClearRegs)
static void CMSEPopCalleeSaves(const TargetInstrInfo &TII, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, bool Thumb1Only)
static void addExclusiveRegPair(MachineInstrBuilder &MIB, MachineOperand &Reg, RegState Flags, bool IsThumb, const TargetRegisterInfo *TRI)
ARM's ldrexd/strexd take a consecutive register pair (represented as a single GPRPair register),...
static void GetDSubRegs(unsigned Reg, NEONRegSpacing RegSpc, const TargetRegisterInfo *TRI, MCRegister &D0, MCRegister &D1, MCRegister &D2, MCRegister &D3)
GetDSubRegs - Get 4 D subregisters of a Q, QQ, or QQQQ register, corresponding to the specified regis...
static MachineOperand getMovOperand(const MachineOperand &MO, unsigned TargetFlag)
static MachineOperand makeImplicit(const MachineOperand &MO)
static cl::opt< bool > VerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden, cl::desc("Verify machine code after expanding ARM pseudos"))
static bool definesOrUsesFPReg(const MachineInstr &MI)
static void determineGPRegsToClear(const MachineInstr &MI, const std::initializer_list< unsigned > &Regs, SmallVectorImpl< unsigned > &ClearRegs)
static void CMSEPushCalleeSaves(const TargetInstrInfo &TII, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, Register JumpReg, const LivePhysRegs &LiveRegs, bool Thumb1Only)
static bool IsAnAddressOperand(const MachineOperand &MO)
#define ARM_EXPAND_PSEUDO_NAME
static const int CMSE_FP_SAVE_SIZE
static const NEONLdStTableEntry * LookupNEONLdSt(unsigned Opcode)
LookupNEONLdSt - Search the NEONLdStTable for information about a NEON load or store pseudo instructi...
static const NEONLdStTableEntry NEONLdStTable[]
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
MachineBasicBlock MachineBasicBlock::iterator MBBI
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
const HexagonInstrInfo * TII
This file implements the LivePhysRegs utility for tracking liveness of physical registers.
Register const TargetRegisterInfo * TRI
Promote Memory to Register
MachineInstr unsigned OpIdx
#define INITIALIZE_PASS(passName, arg, name, cfg, analysis)
static bool contains(SmallPtrSetImpl< ConstantExpr * > &Cache, ConstantExpr *Expr, Constant *C)
static const unsigned FramePtr
bool hasBasePointer(const MachineFunction &MF) const
Register getFrameRegister(const MachineFunction &MF) const override
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
static ARMConstantPoolSymbol * Create(LLVMContext &C, StringRef s, unsigned ID, unsigned char PCAdj)
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
bool isThumb2Function() const
unsigned createPICLabelUId()
bool isThumb1OnlyFunction() const
bool isThumbFunction() const
bool shouldSignReturnAddress() const
unsigned getFramePtrSpillOffset() const
bool isTargetMachO() const
const ARMBaseInstrInfo * getInstrInfo() const override
bool isThumb1Only() const
bool isTargetWindows() const
const ARMBaseRegisterInfo * getRegisterInfo() const override
BitVector & reset()
Reset all bits in the bitvector.
size_type count() const
Returns the number of bits which are set.
size_type size() const
Returns the number of bits in this bitvector.
FunctionPass class - This class is used to implement most global optimizations.
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
bool needsUnwindTableEntry() const
True if this function needs an unwind table.
const HexagonRegisterInfo & getRegisterInfo() const
A set of physical registers with utility functions to track liveness when walking backward/forward th...
bool usesWindowsCFI() const
Wrapper class representing physical registers. Should be passed by value.
LLVM_ABI void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
LLVM_ABI void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
LLVM_ABI iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
LLVM_ABI instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
reverse_iterator rbegin()
void splice(iterator Where, MachineBasicBlock *Other, iterator From)
Take an instruction from MBB 'Other' at the position From, and insert it into this MBB right before '...
MachineInstrBundleIterator< MachineInstr > iterator
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Properties which a MachineFunction may have at a given point in time.
void moveAdditionalCallInfo(const MachineInstr *Old, const MachineInstr *New)
Move the call site info from Old to \New call site info.
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Function & getFunction()
Return the LLVM function that this machine code represents.
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *BB=nullptr, std::optional< UniqueBBID > BBID=std::nullopt)
CreateMachineInstr - Allocate a new MachineInstr.
void insert(iterator MBBI, MachineBasicBlock *MBB)
const TargetMachine & getTarget() const
getTarget - Return the target machine this machine code is compiled with
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
const MachineInstrBuilder & addReg(Register RegNo, RegState Flags={}, unsigned SubReg=0) const
Add a new virtual register operand.
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
const MachineInstrBuilder & add(const MachineOperand &MO) const
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
const MachineInstrBuilder & copyImplicitOps(const MachineInstr &OtherMI) const
Copy all the implicit operands from OtherMI onto this one.
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Representation of each machine instruction.
LLVM_ABI void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
mop_range implicit_operands()
LLVM_ABI bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
LLVM_ABI void dump() const
@ EK_Inline
EK_Inline - Jump table entries are emitted inline at their point of use.
MachineOperand class - Representation of each machine instruction operand.
static MachineOperand CreateMCSymbol(MCSymbol *Sym, unsigned TargetFlags=0)
const GlobalValue * getGlobal() const
void setImplicit(bool Val=true)
static MachineOperand CreateES(const char *SymName, unsigned TargetFlags=0)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
unsigned getTargetFlags() const
static MachineOperand CreateImm(int64_t Val)
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
static MachineOperand CreateJTI(unsigned Idx, unsigned TargetFlags=0)
const char * getSymbolName() const
void setIsUndef(bool Val=true)
Register getReg() const
getReg - Returns the register number.
static MachineOperand CreateGA(const GlobalValue *GV, int64_t Offset, unsigned TargetFlags=0)
MCSymbol * getMCSymbol() const
@ MO_CFIIndex
MCCFIInstruction index.
@ MO_Immediate
Immediate operand.
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
@ MO_MCSymbol
MCSymbol reference (for debug/eh info)
@ MO_Predicate
Generic predicate for ISel.
@ MO_GlobalAddress
Address of a global value.
@ MO_RegisterMask
Mask of preserved registers.
@ MO_ShuffleMask
Other IR Constant for ISel (shuffle masks)
@ MO_CImmediate
Immediate >64bit operand.
@ MO_BlockAddress
Address of a basic block.
@ MO_DbgInstrRef
Integer indices referring to an instruction+operand.
@ MO_MachineBasicBlock
MachineBasicBlock reference.
@ MO_LaneMask
Mask to represent active parts of registers.
@ MO_FrameIndex
Abstract Stack Frame Index.
@ MO_Register
Register operand.
@ MO_ExternalSymbol
Name of external global symbol.
@ MO_IntrinsicID
Intrinsic ID for ISel.
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
@ MO_TargetIndex
Target-dependent index+offset operand.
@ MO_Metadata
Metadata reference (for debug info)
@ MO_FPImmediate
Floating-point immediate operand.
@ MO_RegisterLiveOut
Mask of live-out registers.
int64_t getOffset() const
Return the offset from the symbol in this operand.
Wrapper class representing virtual and physical registers.
constexpr bool isPhysical() const
Return true if the specified register number is in the physical register namespace.
This class consists of common code factored out of the SmallVector class to reduce code duplication b...
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
bool hasFP(const MachineFunction &MF) const
hasFP - Return true if the specified function should have a dedicated frame pointer register.
TargetInstrInfo - Interface to description of machine instruction set.
const MCAsmInfo & getMCAsmInfo() const
Return target specific asm information.
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
virtual const TargetFrameLowering * getFrameLowering() const
self_iterator getIterator()
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
constexpr char Align[]
Key for Kernel::Arg::Metadata::mAlign.
@ GOT_PREL
Thread Local Storage (General Dynamic Mode)
@ MO_LO16
MO_LO16 - On a symbol operand, this represents a relocation containing lower 16 bit of the address.
@ MO_LO_0_7
MO_LO_0_7 - On a symbol operand, this represents a relocation containing bits 0 through 7 of the addr...
@ MO_LO_8_15
MO_LO_8_15 - On a symbol operand, this represents a relocation containing bits 8 through 15 of the ad...
@ MO_HI_8_15
MO_HI_8_15 - On a symbol operand, this represents a relocation containing bits 24 through 31 of the a...
@ MO_HI16
MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address.
@ MO_HI_0_7
MO_HI_0_7 - On a symbol operand, this represents a relocation containing bits 16 through 23 of the ad...
@ MO_GOT
MO_GOT - On a symbol operand, this represents a GOT relative relocation.
unsigned getSOImmTwoPartSecond(unsigned V)
getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal, return the second chunk of ...
bool isSOImmTwoPartVal(unsigned V)
isSOImmTwoPartVal - Return true if the specified value can be obtained by or'ing together two SOImmVa...
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
unsigned getSOImmTwoPartFirst(unsigned V)
getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal, return the first chunk of it...
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Flag
These should be considered private to the implementation of the MCInstrDesc class.
@ HI16
High 16 bits of absolute address.
@ LO16
Low 16 bits of absolute address.
This is an optimization pass for GlobalISel generic memory operations.
auto drop_begin(T &&RangeOrContainer, size_t N=1)
Return a range covering RangeOrContainer with the first N elements excluded.
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
bool operator<(int64_t V1, const APSInt &V2)
LLVM_ABI void finalizeBundle(MachineBasicBlock &MBB, MachineBasicBlock::instr_iterator FirstMI, MachineBasicBlock::instr_iterator LastMI)
finalizeBundle - Finalize a machine instruction bundle which includes a sequence of instructions star...
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
MachineInstrBuilder BuildMI(MachineFunction &MF, const MIMetadata &MIMD, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
RegState
Flags to represent properties of register accesses.
@ Kill
The last use of a register.
@ Define
Register definition.
constexpr RegState getKillRegState(bool B)
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr RegState getDeadRegState(bool B)
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
constexpr RegState getRenamableRegState(bool B)
void sort(IteratorTy Start, IteratorTy End)
LLVM_ABI raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
bool is_sorted(R &&Range, Compare C)
Wrapper function around std::is_sorted to check if elements in a range R are sorted with respect to a...
constexpr RegState getDefRegState(bool B)
class LLVM_GSL_OWNER SmallVector
Forward declaration of SmallVector so that calculateSmallVectorDefaultInlinedElements can reference s...
RegState getRegState(const MachineOperand &RegOp)
Get all register state flags from machine operand RegOp.
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=0)
emitThumbRegPlusImmediate - Emits a series of instructions to materialize a destreg = basereg + immed...
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, Register &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition,...
DWARFExpression::Operation Op
static MachineOperand t1CondCodeOp(bool isDead=false)
Get the operand corresponding to the conditional code result for Thumb1.
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
FunctionPass * createARMExpandPseudoPass()
createARMExpandPseudoPass - returns an instance of the pseudo instruction expansion pass.
unsigned gettBLXrOpcode(const MachineFunction &MF)
unsigned getBLXOpcode(const MachineFunction &MF)
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, ARMCC::CondCodes Pred, Register PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
emitARMRegPlusImmediate / emitT2RegPlusImmediate - Emits a series of instructions to materializea des...
constexpr RegState getUndefRegState(bool B)
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, const DebugLoc &dl, Register DestReg, Register BaseReg, int NumBytes, ARMCC::CondCodes Pred, Register PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
constexpr uint64_t value() const
This is a hole in the type system and should not be abused.