LLVM  14.0.0git
ARMExpandPseudoInsts.cpp
Go to the documentation of this file.
1 //===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains a pass that expands pseudo instructions into target
10 // instructions to allow proper scheduling, if-conversion, and other late
11 // optimizations. This pass should be run after register allocation but before
12 // the post-regalloc scheduling pass.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #include "ARM.h"
17 #include "ARMBaseInstrInfo.h"
18 #include "ARMBaseRegisterInfo.h"
19 #include "ARMConstantPoolValue.h"
20 #include "ARMMachineFunctionInfo.h"
21 #include "ARMSubtarget.h"
26 #include "llvm/Support/Debug.h"
27 
28 using namespace llvm;
29 
30 #define DEBUG_TYPE "arm-pseudo"
31 
32 static cl::opt<bool>
33 VerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden,
34  cl::desc("Verify machine code after expanding ARM pseudos"));
35 
36 #define ARM_EXPAND_PSEUDO_NAME "ARM pseudo instruction expansion pass"
37 
38 namespace {
39  class ARMExpandPseudo : public MachineFunctionPass {
40  public:
41  static char ID;
42  ARMExpandPseudo() : MachineFunctionPass(ID) {}
43 
44  const ARMBaseInstrInfo *TII;
45  const TargetRegisterInfo *TRI;
46  const ARMSubtarget *STI;
47  ARMFunctionInfo *AFI;
48 
49  bool runOnMachineFunction(MachineFunction &Fn) override;
50 
51  MachineFunctionProperties getRequiredProperties() const override {
54  }
55 
56  StringRef getPassName() const override {
58  }
59 
60  private:
61  void TransferImpOps(MachineInstr &OldMI,
63  bool ExpandMI(MachineBasicBlock &MBB,
65  MachineBasicBlock::iterator &NextMBBI);
66  bool ExpandMBB(MachineBasicBlock &MBB);
67  void ExpandVLD(MachineBasicBlock::iterator &MBBI);
68  void ExpandVST(MachineBasicBlock::iterator &MBBI);
69  void ExpandLaneOp(MachineBasicBlock::iterator &MBBI);
70  void ExpandVTBL(MachineBasicBlock::iterator &MBBI,
71  unsigned Opc, bool IsExt);
72  void ExpandMQQPRLoadStore(MachineBasicBlock::iterator &MBBI);
73  void ExpandMOV32BitImm(MachineBasicBlock &MBB,
75  void CMSEClearGPRegs(MachineBasicBlock &MBB,
77  const SmallVectorImpl<unsigned> &ClearRegs,
78  unsigned ClobberReg);
79  MachineBasicBlock &CMSEClearFPRegs(MachineBasicBlock &MBB,
81  MachineBasicBlock &CMSEClearFPRegsV8(MachineBasicBlock &MBB,
83  const BitVector &ClearRegs);
84  MachineBasicBlock &CMSEClearFPRegsV81(MachineBasicBlock &MBB,
86  const BitVector &ClearRegs);
87  void CMSESaveClearFPRegs(MachineBasicBlock &MBB,
89  const LivePhysRegs &LiveRegs,
90  SmallVectorImpl<unsigned> &AvailableRegs);
91  void CMSESaveClearFPRegsV8(MachineBasicBlock &MBB,
93  const LivePhysRegs &LiveRegs,
94  SmallVectorImpl<unsigned> &ScratchRegs);
95  void CMSESaveClearFPRegsV81(MachineBasicBlock &MBB,
97  const LivePhysRegs &LiveRegs);
98  void CMSERestoreFPRegs(MachineBasicBlock &MBB,
100  SmallVectorImpl<unsigned> &AvailableRegs);
101  void CMSERestoreFPRegsV8(MachineBasicBlock &MBB,
103  SmallVectorImpl<unsigned> &AvailableRegs);
104  void CMSERestoreFPRegsV81(MachineBasicBlock &MBB,
106  SmallVectorImpl<unsigned> &AvailableRegs);
107  bool ExpandCMP_SWAP(MachineBasicBlock &MBB,
108  MachineBasicBlock::iterator MBBI, unsigned LdrexOp,
109  unsigned StrexOp, unsigned UxtOp,
110  MachineBasicBlock::iterator &NextMBBI);
111 
112  bool ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
114  MachineBasicBlock::iterator &NextMBBI);
115  };
116  char ARMExpandPseudo::ID = 0;
117 }
118 
120  false)
121 
122 /// TransferImpOps - Transfer implicit operands on the pseudo instruction to
123 /// the instructions created from the expansion.
124 void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI,
127  const MCInstrDesc &Desc = OldMI.getDesc();
128  for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands();
129  i != e; ++i) {
130  const MachineOperand &MO = OldMI.getOperand(i);
131  assert(MO.isReg() && MO.getReg());
132  if (MO.isUse())
133  UseMI.add(MO);
134  else
135  DefMI.add(MO);
136  }
137 }
138 
139 namespace {
140  // Constants for register spacing in NEON load/store instructions.
141  // For quad-register load-lane and store-lane pseudo instructors, the
142  // spacing is initially assumed to be EvenDblSpc, and that is changed to
143  // OddDblSpc depending on the lane number operand.
144  enum NEONRegSpacing {
145  SingleSpc,
146  SingleLowSpc , // Single spacing, low registers, three and four vectors.
147  SingleHighQSpc, // Single spacing, high registers, four vectors.
148  SingleHighTSpc, // Single spacing, high registers, three vectors.
149  EvenDblSpc,
150  OddDblSpc
151  };
152 
153  // Entries for NEON load/store information table. The table is sorted by
154  // PseudoOpc for fast binary-search lookups.
155  struct NEONLdStTableEntry {
156  uint16_t PseudoOpc;
157  uint16_t RealOpc;
158  bool IsLoad;
159  bool isUpdating;
160  bool hasWritebackOperand;
161  uint8_t RegSpacing; // One of type NEONRegSpacing
162  uint8_t NumRegs; // D registers loaded or stored
163  uint8_t RegElts; // elements per D register; used for lane ops
164  // FIXME: Temporary flag to denote whether the real instruction takes
165  // a single register (like the encoding) or all of the registers in
166  // the list (like the asm syntax and the isel DAG). When all definitions
167  // are converted to take only the single encoded register, this will
168  // go away.
169  bool copyAllListRegs;
170 
171  // Comparison methods for binary search of the table.
172  bool operator<(const NEONLdStTableEntry &TE) const {
173  return PseudoOpc < TE.PseudoOpc;
174  }
175  friend bool operator<(const NEONLdStTableEntry &TE, unsigned PseudoOpc) {
176  return TE.PseudoOpc < PseudoOpc;
177  }
178  friend bool LLVM_ATTRIBUTE_UNUSED operator<(unsigned PseudoOpc,
179  const NEONLdStTableEntry &TE) {
180  return PseudoOpc < TE.PseudoOpc;
181  }
182  };
183 }
184 
185 static const NEONLdStTableEntry NEONLdStTable[] = {
186 { ARM::VLD1LNq16Pseudo, ARM::VLD1LNd16, true, false, false, EvenDblSpc, 1, 4 ,true},
187 { ARM::VLD1LNq16Pseudo_UPD, ARM::VLD1LNd16_UPD, true, true, true, EvenDblSpc, 1, 4 ,true},
188 { ARM::VLD1LNq32Pseudo, ARM::VLD1LNd32, true, false, false, EvenDblSpc, 1, 2 ,true},
189 { ARM::VLD1LNq32Pseudo_UPD, ARM::VLD1LNd32_UPD, true, true, true, EvenDblSpc, 1, 2 ,true},
190 { ARM::VLD1LNq8Pseudo, ARM::VLD1LNd8, true, false, false, EvenDblSpc, 1, 8 ,true},
191 { ARM::VLD1LNq8Pseudo_UPD, ARM::VLD1LNd8_UPD, true, true, true, EvenDblSpc, 1, 8 ,true},
192 
193 { ARM::VLD1d16QPseudo, ARM::VLD1d16Q, true, false, false, SingleSpc, 4, 4 ,false},
194 { ARM::VLD1d16QPseudoWB_fixed, ARM::VLD1d16Qwb_fixed, true, true, false, SingleSpc, 4, 4 ,false},
195 { ARM::VLD1d16QPseudoWB_register, ARM::VLD1d16Qwb_register, true, true, true, SingleSpc, 4, 4 ,false},
196 { ARM::VLD1d16TPseudo, ARM::VLD1d16T, true, false, false, SingleSpc, 3, 4 ,false},
197 { ARM::VLD1d16TPseudoWB_fixed, ARM::VLD1d16Twb_fixed, true, true, false, SingleSpc, 3, 4 ,false},
198 { ARM::VLD1d16TPseudoWB_register, ARM::VLD1d16Twb_register, true, true, true, SingleSpc, 3, 4 ,false},
199 
200 { ARM::VLD1d32QPseudo, ARM::VLD1d32Q, true, false, false, SingleSpc, 4, 2 ,false},
201 { ARM::VLD1d32QPseudoWB_fixed, ARM::VLD1d32Qwb_fixed, true, true, false, SingleSpc, 4, 2 ,false},
202 { ARM::VLD1d32QPseudoWB_register, ARM::VLD1d32Qwb_register, true, true, true, SingleSpc, 4, 2 ,false},
203 { ARM::VLD1d32TPseudo, ARM::VLD1d32T, true, false, false, SingleSpc, 3, 2 ,false},
204 { ARM::VLD1d32TPseudoWB_fixed, ARM::VLD1d32Twb_fixed, true, true, false, SingleSpc, 3, 2 ,false},
205 { ARM::VLD1d32TPseudoWB_register, ARM::VLD1d32Twb_register, true, true, true, SingleSpc, 3, 2 ,false},
206 
207 { ARM::VLD1d64QPseudo, ARM::VLD1d64Q, true, false, false, SingleSpc, 4, 1 ,false},
208 { ARM::VLD1d64QPseudoWB_fixed, ARM::VLD1d64Qwb_fixed, true, true, false, SingleSpc, 4, 1 ,false},
209 { ARM::VLD1d64QPseudoWB_register, ARM::VLD1d64Qwb_register, true, true, true, SingleSpc, 4, 1 ,false},
210 { ARM::VLD1d64TPseudo, ARM::VLD1d64T, true, false, false, SingleSpc, 3, 1 ,false},
211 { ARM::VLD1d64TPseudoWB_fixed, ARM::VLD1d64Twb_fixed, true, true, false, SingleSpc, 3, 1 ,false},
212 { ARM::VLD1d64TPseudoWB_register, ARM::VLD1d64Twb_register, true, true, true, SingleSpc, 3, 1 ,false},
213 
214 { ARM::VLD1d8QPseudo, ARM::VLD1d8Q, true, false, false, SingleSpc, 4, 8 ,false},
215 { ARM::VLD1d8QPseudoWB_fixed, ARM::VLD1d8Qwb_fixed, true, true, false, SingleSpc, 4, 8 ,false},
216 { ARM::VLD1d8QPseudoWB_register, ARM::VLD1d8Qwb_register, true, true, true, SingleSpc, 4, 8 ,false},
217 { ARM::VLD1d8TPseudo, ARM::VLD1d8T, true, false, false, SingleSpc, 3, 8 ,false},
218 { ARM::VLD1d8TPseudoWB_fixed, ARM::VLD1d8Twb_fixed, true, true, false, SingleSpc, 3, 8 ,false},
219 { ARM::VLD1d8TPseudoWB_register, ARM::VLD1d8Twb_register, true, true, true, SingleSpc, 3, 8 ,false},
220 
221 { ARM::VLD1q16HighQPseudo, ARM::VLD1d16Q, true, false, false, SingleHighQSpc, 4, 4 ,false},
222 { ARM::VLD1q16HighQPseudo_UPD, ARM::VLD1d16Qwb_fixed, true, true, true, SingleHighQSpc, 4, 4 ,false},
223 { ARM::VLD1q16HighTPseudo, ARM::VLD1d16T, true, false, false, SingleHighTSpc, 3, 4 ,false},
224 { ARM::VLD1q16HighTPseudo_UPD, ARM::VLD1d16Twb_fixed, true, true, true, SingleHighTSpc, 3, 4 ,false},
225 { ARM::VLD1q16LowQPseudo_UPD, ARM::VLD1d16Qwb_fixed, true, true, true, SingleLowSpc, 4, 4 ,false},
226 { ARM::VLD1q16LowTPseudo_UPD, ARM::VLD1d16Twb_fixed, true, true, true, SingleLowSpc, 3, 4 ,false},
227 
228 { ARM::VLD1q32HighQPseudo, ARM::VLD1d32Q, true, false, false, SingleHighQSpc, 4, 2 ,false},
229 { ARM::VLD1q32HighQPseudo_UPD, ARM::VLD1d32Qwb_fixed, true, true, true, SingleHighQSpc, 4, 2 ,false},
230 { ARM::VLD1q32HighTPseudo, ARM::VLD1d32T, true, false, false, SingleHighTSpc, 3, 2 ,false},
231 { ARM::VLD1q32HighTPseudo_UPD, ARM::VLD1d32Twb_fixed, true, true, true, SingleHighTSpc, 3, 2 ,false},
232 { ARM::VLD1q32LowQPseudo_UPD, ARM::VLD1d32Qwb_fixed, true, true, true, SingleLowSpc, 4, 2 ,false},
233 { ARM::VLD1q32LowTPseudo_UPD, ARM::VLD1d32Twb_fixed, true, true, true, SingleLowSpc, 3, 2 ,false},
234 
235 { ARM::VLD1q64HighQPseudo, ARM::VLD1d64Q, true, false, false, SingleHighQSpc, 4, 1 ,false},
236 { ARM::VLD1q64HighQPseudo_UPD, ARM::VLD1d64Qwb_fixed, true, true, true, SingleHighQSpc, 4, 1 ,false},
237 { ARM::VLD1q64HighTPseudo, ARM::VLD1d64T, true, false, false, SingleHighTSpc, 3, 1 ,false},
238 { ARM::VLD1q64HighTPseudo_UPD, ARM::VLD1d64Twb_fixed, true, true, true, SingleHighTSpc, 3, 1 ,false},
239 { ARM::VLD1q64LowQPseudo_UPD, ARM::VLD1d64Qwb_fixed, true, true, true, SingleLowSpc, 4, 1 ,false},
240 { ARM::VLD1q64LowTPseudo_UPD, ARM::VLD1d64Twb_fixed, true, true, true, SingleLowSpc, 3, 1 ,false},
241 
242 { ARM::VLD1q8HighQPseudo, ARM::VLD1d8Q, true, false, false, SingleHighQSpc, 4, 8 ,false},
243 { ARM::VLD1q8HighQPseudo_UPD, ARM::VLD1d8Qwb_fixed, true, true, true, SingleHighQSpc, 4, 8 ,false},
244 { ARM::VLD1q8HighTPseudo, ARM::VLD1d8T, true, false, false, SingleHighTSpc, 3, 8 ,false},
245 { ARM::VLD1q8HighTPseudo_UPD, ARM::VLD1d8Twb_fixed, true, true, true, SingleHighTSpc, 3, 8 ,false},
246 { ARM::VLD1q8LowQPseudo_UPD, ARM::VLD1d8Qwb_fixed, true, true, true, SingleLowSpc, 4, 8 ,false},
247 { ARM::VLD1q8LowTPseudo_UPD, ARM::VLD1d8Twb_fixed, true, true, true, SingleLowSpc, 3, 8 ,false},
248 
249 { ARM::VLD2DUPq16EvenPseudo, ARM::VLD2DUPd16x2, true, false, false, EvenDblSpc, 2, 4 ,false},
250 { ARM::VLD2DUPq16OddPseudo, ARM::VLD2DUPd16x2, true, false, false, OddDblSpc, 2, 4 ,false},
251 { ARM::VLD2DUPq16OddPseudoWB_fixed, ARM::VLD2DUPd16x2wb_fixed, true, true, false, OddDblSpc, 2, 4 ,false},
252 { ARM::VLD2DUPq16OddPseudoWB_register, ARM::VLD2DUPd16x2wb_register, true, true, true, OddDblSpc, 2, 4 ,false},
253 { ARM::VLD2DUPq32EvenPseudo, ARM::VLD2DUPd32x2, true, false, false, EvenDblSpc, 2, 2 ,false},
254 { ARM::VLD2DUPq32OddPseudo, ARM::VLD2DUPd32x2, true, false, false, OddDblSpc, 2, 2 ,false},
255 { ARM::VLD2DUPq32OddPseudoWB_fixed, ARM::VLD2DUPd32x2wb_fixed, true, true, false, OddDblSpc, 2, 2 ,false},
256 { ARM::VLD2DUPq32OddPseudoWB_register, ARM::VLD2DUPd32x2wb_register, true, true, true, OddDblSpc, 2, 2 ,false},
257 { ARM::VLD2DUPq8EvenPseudo, ARM::VLD2DUPd8x2, true, false, false, EvenDblSpc, 2, 8 ,false},
258 { ARM::VLD2DUPq8OddPseudo, ARM::VLD2DUPd8x2, true, false, false, OddDblSpc, 2, 8 ,false},
259 { ARM::VLD2DUPq8OddPseudoWB_fixed, ARM::VLD2DUPd8x2wb_fixed, true, true, false, OddDblSpc, 2, 8 ,false},
260 { ARM::VLD2DUPq8OddPseudoWB_register, ARM::VLD2DUPd8x2wb_register, true, true, true, OddDblSpc, 2, 8 ,false},
261 
262 { ARM::VLD2LNd16Pseudo, ARM::VLD2LNd16, true, false, false, SingleSpc, 2, 4 ,true},
263 { ARM::VLD2LNd16Pseudo_UPD, ARM::VLD2LNd16_UPD, true, true, true, SingleSpc, 2, 4 ,true},
264 { ARM::VLD2LNd32Pseudo, ARM::VLD2LNd32, true, false, false, SingleSpc, 2, 2 ,true},
265 { ARM::VLD2LNd32Pseudo_UPD, ARM::VLD2LNd32_UPD, true, true, true, SingleSpc, 2, 2 ,true},
266 { ARM::VLD2LNd8Pseudo, ARM::VLD2LNd8, true, false, false, SingleSpc, 2, 8 ,true},
267 { ARM::VLD2LNd8Pseudo_UPD, ARM::VLD2LNd8_UPD, true, true, true, SingleSpc, 2, 8 ,true},
268 { ARM::VLD2LNq16Pseudo, ARM::VLD2LNq16, true, false, false, EvenDblSpc, 2, 4 ,true},
269 { ARM::VLD2LNq16Pseudo_UPD, ARM::VLD2LNq16_UPD, true, true, true, EvenDblSpc, 2, 4 ,true},
270 { ARM::VLD2LNq32Pseudo, ARM::VLD2LNq32, true, false, false, EvenDblSpc, 2, 2 ,true},
271 { ARM::VLD2LNq32Pseudo_UPD, ARM::VLD2LNq32_UPD, true, true, true, EvenDblSpc, 2, 2 ,true},
272 
273 { ARM::VLD2q16Pseudo, ARM::VLD2q16, true, false, false, SingleSpc, 4, 4 ,false},
274 { ARM::VLD2q16PseudoWB_fixed, ARM::VLD2q16wb_fixed, true, true, false, SingleSpc, 4, 4 ,false},
275 { ARM::VLD2q16PseudoWB_register, ARM::VLD2q16wb_register, true, true, true, SingleSpc, 4, 4 ,false},
276 { ARM::VLD2q32Pseudo, ARM::VLD2q32, true, false, false, SingleSpc, 4, 2 ,false},
277 { ARM::VLD2q32PseudoWB_fixed, ARM::VLD2q32wb_fixed, true, true, false, SingleSpc, 4, 2 ,false},
278 { ARM::VLD2q32PseudoWB_register, ARM::VLD2q32wb_register, true, true, true, SingleSpc, 4, 2 ,false},
279 { ARM::VLD2q8Pseudo, ARM::VLD2q8, true, false, false, SingleSpc, 4, 8 ,false},
280 { ARM::VLD2q8PseudoWB_fixed, ARM::VLD2q8wb_fixed, true, true, false, SingleSpc, 4, 8 ,false},
281 { ARM::VLD2q8PseudoWB_register, ARM::VLD2q8wb_register, true, true, true, SingleSpc, 4, 8 ,false},
282 
283 { ARM::VLD3DUPd16Pseudo, ARM::VLD3DUPd16, true, false, false, SingleSpc, 3, 4,true},
284 { ARM::VLD3DUPd16Pseudo_UPD, ARM::VLD3DUPd16_UPD, true, true, true, SingleSpc, 3, 4,true},
285 { ARM::VLD3DUPd32Pseudo, ARM::VLD3DUPd32, true, false, false, SingleSpc, 3, 2,true},
286 { ARM::VLD3DUPd32Pseudo_UPD, ARM::VLD3DUPd32_UPD, true, true, true, SingleSpc, 3, 2,true},
287 { ARM::VLD3DUPd8Pseudo, ARM::VLD3DUPd8, true, false, false, SingleSpc, 3, 8,true},
288 { ARM::VLD3DUPd8Pseudo_UPD, ARM::VLD3DUPd8_UPD, true, true, true, SingleSpc, 3, 8,true},
289 { ARM::VLD3DUPq16EvenPseudo, ARM::VLD3DUPq16, true, false, false, EvenDblSpc, 3, 4 ,true},
290 { ARM::VLD3DUPq16OddPseudo, ARM::VLD3DUPq16, true, false, false, OddDblSpc, 3, 4 ,true},
291 { ARM::VLD3DUPq16OddPseudo_UPD, ARM::VLD3DUPq16_UPD, true, true, true, OddDblSpc, 3, 4 ,true},
292 { ARM::VLD3DUPq32EvenPseudo, ARM::VLD3DUPq32, true, false, false, EvenDblSpc, 3, 2 ,true},
293 { ARM::VLD3DUPq32OddPseudo, ARM::VLD3DUPq32, true, false, false, OddDblSpc, 3, 2 ,true},
294 { ARM::VLD3DUPq32OddPseudo_UPD, ARM::VLD3DUPq32_UPD, true, true, true, OddDblSpc, 3, 2 ,true},
295 { ARM::VLD3DUPq8EvenPseudo, ARM::VLD3DUPq8, true, false, false, EvenDblSpc, 3, 8 ,true},
296 { ARM::VLD3DUPq8OddPseudo, ARM::VLD3DUPq8, true, false, false, OddDblSpc, 3, 8 ,true},
297 { ARM::VLD3DUPq8OddPseudo_UPD, ARM::VLD3DUPq8_UPD, true, true, true, OddDblSpc, 3, 8 ,true},
298 
299 { ARM::VLD3LNd16Pseudo, ARM::VLD3LNd16, true, false, false, SingleSpc, 3, 4 ,true},
300 { ARM::VLD3LNd16Pseudo_UPD, ARM::VLD3LNd16_UPD, true, true, true, SingleSpc, 3, 4 ,true},
301 { ARM::VLD3LNd32Pseudo, ARM::VLD3LNd32, true, false, false, SingleSpc, 3, 2 ,true},
302 { ARM::VLD3LNd32Pseudo_UPD, ARM::VLD3LNd32_UPD, true, true, true, SingleSpc, 3, 2 ,true},
303 { ARM::VLD3LNd8Pseudo, ARM::VLD3LNd8, true, false, false, SingleSpc, 3, 8 ,true},
304 { ARM::VLD3LNd8Pseudo_UPD, ARM::VLD3LNd8_UPD, true, true, true, SingleSpc, 3, 8 ,true},
305 { ARM::VLD3LNq16Pseudo, ARM::VLD3LNq16, true, false, false, EvenDblSpc, 3, 4 ,true},
306 { ARM::VLD3LNq16Pseudo_UPD, ARM::VLD3LNq16_UPD, true, true, true, EvenDblSpc, 3, 4 ,true},
307 { ARM::VLD3LNq32Pseudo, ARM::VLD3LNq32, true, false, false, EvenDblSpc, 3, 2 ,true},
308 { ARM::VLD3LNq32Pseudo_UPD, ARM::VLD3LNq32_UPD, true, true, true, EvenDblSpc, 3, 2 ,true},
309 
310 { ARM::VLD3d16Pseudo, ARM::VLD3d16, true, false, false, SingleSpc, 3, 4 ,true},
311 { ARM::VLD3d16Pseudo_UPD, ARM::VLD3d16_UPD, true, true, true, SingleSpc, 3, 4 ,true},
312 { ARM::VLD3d32Pseudo, ARM::VLD3d32, true, false, false, SingleSpc, 3, 2 ,true},
313 { ARM::VLD3d32Pseudo_UPD, ARM::VLD3d32_UPD, true, true, true, SingleSpc, 3, 2 ,true},
314 { ARM::VLD3d8Pseudo, ARM::VLD3d8, true, false, false, SingleSpc, 3, 8 ,true},
315 { ARM::VLD3d8Pseudo_UPD, ARM::VLD3d8_UPD, true, true, true, SingleSpc, 3, 8 ,true},
316 
317 { ARM::VLD3q16Pseudo_UPD, ARM::VLD3q16_UPD, true, true, true, EvenDblSpc, 3, 4 ,true},
318 { ARM::VLD3q16oddPseudo, ARM::VLD3q16, true, false, false, OddDblSpc, 3, 4 ,true},
319 { ARM::VLD3q16oddPseudo_UPD, ARM::VLD3q16_UPD, true, true, true, OddDblSpc, 3, 4 ,true},
320 { ARM::VLD3q32Pseudo_UPD, ARM::VLD3q32_UPD, true, true, true, EvenDblSpc, 3, 2 ,true},
321 { ARM::VLD3q32oddPseudo, ARM::VLD3q32, true, false, false, OddDblSpc, 3, 2 ,true},
322 { ARM::VLD3q32oddPseudo_UPD, ARM::VLD3q32_UPD, true, true, true, OddDblSpc, 3, 2 ,true},
323 { ARM::VLD3q8Pseudo_UPD, ARM::VLD3q8_UPD, true, true, true, EvenDblSpc, 3, 8 ,true},
324 { ARM::VLD3q8oddPseudo, ARM::VLD3q8, true, false, false, OddDblSpc, 3, 8 ,true},
325 { ARM::VLD3q8oddPseudo_UPD, ARM::VLD3q8_UPD, true, true, true, OddDblSpc, 3, 8 ,true},
326 
327 { ARM::VLD4DUPd16Pseudo, ARM::VLD4DUPd16, true, false, false, SingleSpc, 4, 4,true},
328 { ARM::VLD4DUPd16Pseudo_UPD, ARM::VLD4DUPd16_UPD, true, true, true, SingleSpc, 4, 4,true},
329 { ARM::VLD4DUPd32Pseudo, ARM::VLD4DUPd32, true, false, false, SingleSpc, 4, 2,true},
330 { ARM::VLD4DUPd32Pseudo_UPD, ARM::VLD4DUPd32_UPD, true, true, true, SingleSpc, 4, 2,true},
331 { ARM::VLD4DUPd8Pseudo, ARM::VLD4DUPd8, true, false, false, SingleSpc, 4, 8,true},
332 { ARM::VLD4DUPd8Pseudo_UPD, ARM::VLD4DUPd8_UPD, true, true, true, SingleSpc, 4, 8,true},
333 { ARM::VLD4DUPq16EvenPseudo, ARM::VLD4DUPq16, true, false, false, EvenDblSpc, 4, 4 ,true},
334 { ARM::VLD4DUPq16OddPseudo, ARM::VLD4DUPq16, true, false, false, OddDblSpc, 4, 4 ,true},
335 { ARM::VLD4DUPq16OddPseudo_UPD, ARM::VLD4DUPq16_UPD, true, true, true, OddDblSpc, 4, 4 ,true},
336 { ARM::VLD4DUPq32EvenPseudo, ARM::VLD4DUPq32, true, false, false, EvenDblSpc, 4, 2 ,true},
337 { ARM::VLD4DUPq32OddPseudo, ARM::VLD4DUPq32, true, false, false, OddDblSpc, 4, 2 ,true},
338 { ARM::VLD4DUPq32OddPseudo_UPD, ARM::VLD4DUPq32_UPD, true, true, true, OddDblSpc, 4, 2 ,true},
339 { ARM::VLD4DUPq8EvenPseudo, ARM::VLD4DUPq8, true, false, false, EvenDblSpc, 4, 8 ,true},
340 { ARM::VLD4DUPq8OddPseudo, ARM::VLD4DUPq8, true, false, false, OddDblSpc, 4, 8 ,true},
341 { ARM::VLD4DUPq8OddPseudo_UPD, ARM::VLD4DUPq8_UPD, true, true, true, OddDblSpc, 4, 8 ,true},
342 
343 { ARM::VLD4LNd16Pseudo, ARM::VLD4LNd16, true, false, false, SingleSpc, 4, 4 ,true},
344 { ARM::VLD4LNd16Pseudo_UPD, ARM::VLD4LNd16_UPD, true, true, true, SingleSpc, 4, 4 ,true},
345 { ARM::VLD4LNd32Pseudo, ARM::VLD4LNd32, true, false, false, SingleSpc, 4, 2 ,true},
346 { ARM::VLD4LNd32Pseudo_UPD, ARM::VLD4LNd32_UPD, true, true, true, SingleSpc, 4, 2 ,true},
347 { ARM::VLD4LNd8Pseudo, ARM::VLD4LNd8, true, false, false, SingleSpc, 4, 8 ,true},
348 { ARM::VLD4LNd8Pseudo_UPD, ARM::VLD4LNd8_UPD, true, true, true, SingleSpc, 4, 8 ,true},
349 { ARM::VLD4LNq16Pseudo, ARM::VLD4LNq16, true, false, false, EvenDblSpc, 4, 4 ,true},
350 { ARM::VLD4LNq16Pseudo_UPD, ARM::VLD4LNq16_UPD, true, true, true, EvenDblSpc, 4, 4 ,true},
351 { ARM::VLD4LNq32Pseudo, ARM::VLD4LNq32, true, false, false, EvenDblSpc, 4, 2 ,true},
352 { ARM::VLD4LNq32Pseudo_UPD, ARM::VLD4LNq32_UPD, true, true, true, EvenDblSpc, 4, 2 ,true},
353 
354 { ARM::VLD4d16Pseudo, ARM::VLD4d16, true, false, false, SingleSpc, 4, 4 ,true},
355 { ARM::VLD4d16Pseudo_UPD, ARM::VLD4d16_UPD, true, true, true, SingleSpc, 4, 4 ,true},
356 { ARM::VLD4d32Pseudo, ARM::VLD4d32, true, false, false, SingleSpc, 4, 2 ,true},
357 { ARM::VLD4d32Pseudo_UPD, ARM::VLD4d32_UPD, true, true, true, SingleSpc, 4, 2 ,true},
358 { ARM::VLD4d8Pseudo, ARM::VLD4d8, true, false, false, SingleSpc, 4, 8 ,true},
359 { ARM::VLD4d8Pseudo_UPD, ARM::VLD4d8_UPD, true, true, true, SingleSpc, 4, 8 ,true},
360 
361 { ARM::VLD4q16Pseudo_UPD, ARM::VLD4q16_UPD, true, true, true, EvenDblSpc, 4, 4 ,true},
362 { ARM::VLD4q16oddPseudo, ARM::VLD4q16, true, false, false, OddDblSpc, 4, 4 ,true},
363 { ARM::VLD4q16oddPseudo_UPD, ARM::VLD4q16_UPD, true, true, true, OddDblSpc, 4, 4 ,true},
364 { ARM::VLD4q32Pseudo_UPD, ARM::VLD4q32_UPD, true, true, true, EvenDblSpc, 4, 2 ,true},
365 { ARM::VLD4q32oddPseudo, ARM::VLD4q32, true, false, false, OddDblSpc, 4, 2 ,true},
366 { ARM::VLD4q32oddPseudo_UPD, ARM::VLD4q32_UPD, true, true, true, OddDblSpc, 4, 2 ,true},
367 { ARM::VLD4q8Pseudo_UPD, ARM::VLD4q8_UPD, true, true, true, EvenDblSpc, 4, 8 ,true},
368 { ARM::VLD4q8oddPseudo, ARM::VLD4q8, true, false, false, OddDblSpc, 4, 8 ,true},
369 { ARM::VLD4q8oddPseudo_UPD, ARM::VLD4q8_UPD, true, true, true, OddDblSpc, 4, 8 ,true},
370 
371 { ARM::VST1LNq16Pseudo, ARM::VST1LNd16, false, false, false, EvenDblSpc, 1, 4 ,true},
372 { ARM::VST1LNq16Pseudo_UPD, ARM::VST1LNd16_UPD, false, true, true, EvenDblSpc, 1, 4 ,true},
373 { ARM::VST1LNq32Pseudo, ARM::VST1LNd32, false, false, false, EvenDblSpc, 1, 2 ,true},
374 { ARM::VST1LNq32Pseudo_UPD, ARM::VST1LNd32_UPD, false, true, true, EvenDblSpc, 1, 2 ,true},
375 { ARM::VST1LNq8Pseudo, ARM::VST1LNd8, false, false, false, EvenDblSpc, 1, 8 ,true},
376 { ARM::VST1LNq8Pseudo_UPD, ARM::VST1LNd8_UPD, false, true, true, EvenDblSpc, 1, 8 ,true},
377 
378 { ARM::VST1d16QPseudo, ARM::VST1d16Q, false, false, false, SingleSpc, 4, 4 ,false},
379 { ARM::VST1d16QPseudoWB_fixed, ARM::VST1d16Qwb_fixed, false, true, false, SingleSpc, 4, 4 ,false},
380 { ARM::VST1d16QPseudoWB_register, ARM::VST1d16Qwb_register, false, true, true, SingleSpc, 4, 4 ,false},
381 { ARM::VST1d16TPseudo, ARM::VST1d16T, false, false, false, SingleSpc, 3, 4 ,false},
382 { ARM::VST1d16TPseudoWB_fixed, ARM::VST1d16Twb_fixed, false, true, false, SingleSpc, 3, 4 ,false},
383 { ARM::VST1d16TPseudoWB_register, ARM::VST1d16Twb_register, false, true, true, SingleSpc, 3, 4 ,false},
384 
385 { ARM::VST1d32QPseudo, ARM::VST1d32Q, false, false, false, SingleSpc, 4, 2 ,false},
386 { ARM::VST1d32QPseudoWB_fixed, ARM::VST1d32Qwb_fixed, false, true, false, SingleSpc, 4, 2 ,false},
387 { ARM::VST1d32QPseudoWB_register, ARM::VST1d32Qwb_register, false, true, true, SingleSpc, 4, 2 ,false},
388 { ARM::VST1d32TPseudo, ARM::VST1d32T, false, false, false, SingleSpc, 3, 2 ,false},
389 { ARM::VST1d32TPseudoWB_fixed, ARM::VST1d32Twb_fixed, false, true, false, SingleSpc, 3, 2 ,false},
390 { ARM::VST1d32TPseudoWB_register, ARM::VST1d32Twb_register, false, true, true, SingleSpc, 3, 2 ,false},
391 
392 { ARM::VST1d64QPseudo, ARM::VST1d64Q, false, false, false, SingleSpc, 4, 1 ,false},
393 { ARM::VST1d64QPseudoWB_fixed, ARM::VST1d64Qwb_fixed, false, true, false, SingleSpc, 4, 1 ,false},
394 { ARM::VST1d64QPseudoWB_register, ARM::VST1d64Qwb_register, false, true, true, SingleSpc, 4, 1 ,false},
395 { ARM::VST1d64TPseudo, ARM::VST1d64T, false, false, false, SingleSpc, 3, 1 ,false},
396 { ARM::VST1d64TPseudoWB_fixed, ARM::VST1d64Twb_fixed, false, true, false, SingleSpc, 3, 1 ,false},
397 { ARM::VST1d64TPseudoWB_register, ARM::VST1d64Twb_register, false, true, true, SingleSpc, 3, 1 ,false},
398 
399 { ARM::VST1d8QPseudo, ARM::VST1d8Q, false, false, false, SingleSpc, 4, 8 ,false},
400 { ARM::VST1d8QPseudoWB_fixed, ARM::VST1d8Qwb_fixed, false, true, false, SingleSpc, 4, 8 ,false},
401 { ARM::VST1d8QPseudoWB_register, ARM::VST1d8Qwb_register, false, true, true, SingleSpc, 4, 8 ,false},
402 { ARM::VST1d8TPseudo, ARM::VST1d8T, false, false, false, SingleSpc, 3, 8 ,false},
403 { ARM::VST1d8TPseudoWB_fixed, ARM::VST1d8Twb_fixed, false, true, false, SingleSpc, 3, 8 ,false},
404 { ARM::VST1d8TPseudoWB_register, ARM::VST1d8Twb_register, false, true, true, SingleSpc, 3, 8 ,false},
405 
406 { ARM::VST1q16HighQPseudo, ARM::VST1d16Q, false, false, false, SingleHighQSpc, 4, 4 ,false},
407 { ARM::VST1q16HighQPseudo_UPD, ARM::VST1d16Qwb_fixed, false, true, true, SingleHighQSpc, 4, 8 ,false},
408 { ARM::VST1q16HighTPseudo, ARM::VST1d16T, false, false, false, SingleHighTSpc, 3, 4 ,false},
409 { ARM::VST1q16HighTPseudo_UPD, ARM::VST1d16Twb_fixed, false, true, true, SingleHighTSpc, 3, 4 ,false},
410 { ARM::VST1q16LowQPseudo_UPD, ARM::VST1d16Qwb_fixed, false, true, true, SingleLowSpc, 4, 4 ,false},
411 { ARM::VST1q16LowTPseudo_UPD, ARM::VST1d16Twb_fixed, false, true, true, SingleLowSpc, 3, 4 ,false},
412 
413 { ARM::VST1q32HighQPseudo, ARM::VST1d32Q, false, false, false, SingleHighQSpc, 4, 2 ,false},
414 { ARM::VST1q32HighQPseudo_UPD, ARM::VST1d32Qwb_fixed, false, true, true, SingleHighQSpc, 4, 8 ,false},
415 { ARM::VST1q32HighTPseudo, ARM::VST1d32T, false, false, false, SingleHighTSpc, 3, 2 ,false},
416 { ARM::VST1q32HighTPseudo_UPD, ARM::VST1d32Twb_fixed, false, true, true, SingleHighTSpc, 3, 2 ,false},
417 { ARM::VST1q32LowQPseudo_UPD, ARM::VST1d32Qwb_fixed, false, true, true, SingleLowSpc, 4, 2 ,false},
418 { ARM::VST1q32LowTPseudo_UPD, ARM::VST1d32Twb_fixed, false, true, true, SingleLowSpc, 3, 2 ,false},
419 
420 { ARM::VST1q64HighQPseudo, ARM::VST1d64Q, false, false, false, SingleHighQSpc, 4, 1 ,false},
421 { ARM::VST1q64HighQPseudo_UPD, ARM::VST1d64Qwb_fixed, false, true, true, SingleHighQSpc, 4, 8 ,false},
422 { ARM::VST1q64HighTPseudo, ARM::VST1d64T, false, false, false, SingleHighTSpc, 3, 1 ,false},
423 { ARM::VST1q64HighTPseudo_UPD, ARM::VST1d64Twb_fixed, false, true, true, SingleHighTSpc, 3, 1 ,false},
424 { ARM::VST1q64LowQPseudo_UPD, ARM::VST1d64Qwb_fixed, false, true, true, SingleLowSpc, 4, 1 ,false},
425 { ARM::VST1q64LowTPseudo_UPD, ARM::VST1d64Twb_fixed, false, true, true, SingleLowSpc, 3, 1 ,false},
426 
427 { ARM::VST1q8HighQPseudo, ARM::VST1d8Q, false, false, false, SingleHighQSpc, 4, 8 ,false},
428 { ARM::VST1q8HighQPseudo_UPD, ARM::VST1d8Qwb_fixed, false, true, true, SingleHighQSpc, 4, 8 ,false},
429 { ARM::VST1q8HighTPseudo, ARM::VST1d8T, false, false, false, SingleHighTSpc, 3, 8 ,false},
430 { ARM::VST1q8HighTPseudo_UPD, ARM::VST1d8Twb_fixed, false, true, true, SingleHighTSpc, 3, 8 ,false},
431 { ARM::VST1q8LowQPseudo_UPD, ARM::VST1d8Qwb_fixed, false, true, true, SingleLowSpc, 4, 8 ,false},
432 { ARM::VST1q8LowTPseudo_UPD, ARM::VST1d8Twb_fixed, false, true, true, SingleLowSpc, 3, 8 ,false},
433 
434 { ARM::VST2LNd16Pseudo, ARM::VST2LNd16, false, false, false, SingleSpc, 2, 4 ,true},
435 { ARM::VST2LNd16Pseudo_UPD, ARM::VST2LNd16_UPD, false, true, true, SingleSpc, 2, 4 ,true},
436 { ARM::VST2LNd32Pseudo, ARM::VST2LNd32, false, false, false, SingleSpc, 2, 2 ,true},
437 { ARM::VST2LNd32Pseudo_UPD, ARM::VST2LNd32_UPD, false, true, true, SingleSpc, 2, 2 ,true},
438 { ARM::VST2LNd8Pseudo, ARM::VST2LNd8, false, false, false, SingleSpc, 2, 8 ,true},
439 { ARM::VST2LNd8Pseudo_UPD, ARM::VST2LNd8_UPD, false, true, true, SingleSpc, 2, 8 ,true},
440 { ARM::VST2LNq16Pseudo, ARM::VST2LNq16, false, false, false, EvenDblSpc, 2, 4,true},
441 { ARM::VST2LNq16Pseudo_UPD, ARM::VST2LNq16_UPD, false, true, true, EvenDblSpc, 2, 4,true},
442 { ARM::VST2LNq32Pseudo, ARM::VST2LNq32, false, false, false, EvenDblSpc, 2, 2,true},
443 { ARM::VST2LNq32Pseudo_UPD, ARM::VST2LNq32_UPD, false, true, true, EvenDblSpc, 2, 2,true},
444 
445 { ARM::VST2q16Pseudo, ARM::VST2q16, false, false, false, SingleSpc, 4, 4 ,false},
446 { ARM::VST2q16PseudoWB_fixed, ARM::VST2q16wb_fixed, false, true, false, SingleSpc, 4, 4 ,false},
447 { ARM::VST2q16PseudoWB_register, ARM::VST2q16wb_register, false, true, true, SingleSpc, 4, 4 ,false},
448 { ARM::VST2q32Pseudo, ARM::VST2q32, false, false, false, SingleSpc, 4, 2 ,false},
449 { ARM::VST2q32PseudoWB_fixed, ARM::VST2q32wb_fixed, false, true, false, SingleSpc, 4, 2 ,false},
450 { ARM::VST2q32PseudoWB_register, ARM::VST2q32wb_register, false, true, true, SingleSpc, 4, 2 ,false},
451 { ARM::VST2q8Pseudo, ARM::VST2q8, false, false, false, SingleSpc, 4, 8 ,false},
452 { ARM::VST2q8PseudoWB_fixed, ARM::VST2q8wb_fixed, false, true, false, SingleSpc, 4, 8 ,false},
453 { ARM::VST2q8PseudoWB_register, ARM::VST2q8wb_register, false, true, true, SingleSpc, 4, 8 ,false},
454 
455 { ARM::VST3LNd16Pseudo, ARM::VST3LNd16, false, false, false, SingleSpc, 3, 4 ,true},
456 { ARM::VST3LNd16Pseudo_UPD, ARM::VST3LNd16_UPD, false, true, true, SingleSpc, 3, 4 ,true},
457 { ARM::VST3LNd32Pseudo, ARM::VST3LNd32, false, false, false, SingleSpc, 3, 2 ,true},
458 { ARM::VST3LNd32Pseudo_UPD, ARM::VST3LNd32_UPD, false, true, true, SingleSpc, 3, 2 ,true},
459 { ARM::VST3LNd8Pseudo, ARM::VST3LNd8, false, false, false, SingleSpc, 3, 8 ,true},
460 { ARM::VST3LNd8Pseudo_UPD, ARM::VST3LNd8_UPD, false, true, true, SingleSpc, 3, 8 ,true},
461 { ARM::VST3LNq16Pseudo, ARM::VST3LNq16, false, false, false, EvenDblSpc, 3, 4,true},
462 { ARM::VST3LNq16Pseudo_UPD, ARM::VST3LNq16_UPD, false, true, true, EvenDblSpc, 3, 4,true},
463 { ARM::VST3LNq32Pseudo, ARM::VST3LNq32, false, false, false, EvenDblSpc, 3, 2,true},
464 { ARM::VST3LNq32Pseudo_UPD, ARM::VST3LNq32_UPD, false, true, true, EvenDblSpc, 3, 2,true},
465 
466 { ARM::VST3d16Pseudo, ARM::VST3d16, false, false, false, SingleSpc, 3, 4 ,true},
467 { ARM::VST3d16Pseudo_UPD, ARM::VST3d16_UPD, false, true, true, SingleSpc, 3, 4 ,true},
468 { ARM::VST3d32Pseudo, ARM::VST3d32, false, false, false, SingleSpc, 3, 2 ,true},
469 { ARM::VST3d32Pseudo_UPD, ARM::VST3d32_UPD, false, true, true, SingleSpc, 3, 2 ,true},
470 { ARM::VST3d8Pseudo, ARM::VST3d8, false, false, false, SingleSpc, 3, 8 ,true},
471 { ARM::VST3d8Pseudo_UPD, ARM::VST3d8_UPD, false, true, true, SingleSpc, 3, 8 ,true},
472 
473 { ARM::VST3q16Pseudo_UPD, ARM::VST3q16_UPD, false, true, true, EvenDblSpc, 3, 4 ,true},
474 { ARM::VST3q16oddPseudo, ARM::VST3q16, false, false, false, OddDblSpc, 3, 4 ,true},
475 { ARM::VST3q16oddPseudo_UPD, ARM::VST3q16_UPD, false, true, true, OddDblSpc, 3, 4 ,true},
476 { ARM::VST3q32Pseudo_UPD, ARM::VST3q32_UPD, false, true, true, EvenDblSpc, 3, 2 ,true},
477 { ARM::VST3q32oddPseudo, ARM::VST3q32, false, false, false, OddDblSpc, 3, 2 ,true},
478 { ARM::VST3q32oddPseudo_UPD, ARM::VST3q32_UPD, false, true, true, OddDblSpc, 3, 2 ,true},
479 { ARM::VST3q8Pseudo_UPD, ARM::VST3q8_UPD, false, true, true, EvenDblSpc, 3, 8 ,true},
480 { ARM::VST3q8oddPseudo, ARM::VST3q8, false, false, false, OddDblSpc, 3, 8 ,true},
481 { ARM::VST3q8oddPseudo_UPD, ARM::VST3q8_UPD, false, true, true, OddDblSpc, 3, 8 ,true},
482 
483 { ARM::VST4LNd16Pseudo, ARM::VST4LNd16, false, false, false, SingleSpc, 4, 4 ,true},
484 { ARM::VST4LNd16Pseudo_UPD, ARM::VST4LNd16_UPD, false, true, true, SingleSpc, 4, 4 ,true},
485 { ARM::VST4LNd32Pseudo, ARM::VST4LNd32, false, false, false, SingleSpc, 4, 2 ,true},
486 { ARM::VST4LNd32Pseudo_UPD, ARM::VST4LNd32_UPD, false, true, true, SingleSpc, 4, 2 ,true},
487 { ARM::VST4LNd8Pseudo, ARM::VST4LNd8, false, false, false, SingleSpc, 4, 8 ,true},
488 { ARM::VST4LNd8Pseudo_UPD, ARM::VST4LNd8_UPD, false, true, true, SingleSpc, 4, 8 ,true},
489 { ARM::VST4LNq16Pseudo, ARM::VST4LNq16, false, false, false, EvenDblSpc, 4, 4,true},
490 { ARM::VST4LNq16Pseudo_UPD, ARM::VST4LNq16_UPD, false, true, true, EvenDblSpc, 4, 4,true},
491 { ARM::VST4LNq32Pseudo, ARM::VST4LNq32, false, false, false, EvenDblSpc, 4, 2,true},
492 { ARM::VST4LNq32Pseudo_UPD, ARM::VST4LNq32_UPD, false, true, true, EvenDblSpc, 4, 2,true},
493 
494 { ARM::VST4d16Pseudo, ARM::VST4d16, false, false, false, SingleSpc, 4, 4 ,true},
495 { ARM::VST4d16Pseudo_UPD, ARM::VST4d16_UPD, false, true, true, SingleSpc, 4, 4 ,true},
496 { ARM::VST4d32Pseudo, ARM::VST4d32, false, false, false, SingleSpc, 4, 2 ,true},
497 { ARM::VST4d32Pseudo_UPD, ARM::VST4d32_UPD, false, true, true, SingleSpc, 4, 2 ,true},
498 { ARM::VST4d8Pseudo, ARM::VST4d8, false, false, false, SingleSpc, 4, 8 ,true},
499 { ARM::VST4d8Pseudo_UPD, ARM::VST4d8_UPD, false, true, true, SingleSpc, 4, 8 ,true},
500 
501 { ARM::VST4q16Pseudo_UPD, ARM::VST4q16_UPD, false, true, true, EvenDblSpc, 4, 4 ,true},
502 { ARM::VST4q16oddPseudo, ARM::VST4q16, false, false, false, OddDblSpc, 4, 4 ,true},
503 { ARM::VST4q16oddPseudo_UPD, ARM::VST4q16_UPD, false, true, true, OddDblSpc, 4, 4 ,true},
504 { ARM::VST4q32Pseudo_UPD, ARM::VST4q32_UPD, false, true, true, EvenDblSpc, 4, 2 ,true},
505 { ARM::VST4q32oddPseudo, ARM::VST4q32, false, false, false, OddDblSpc, 4, 2 ,true},
506 { ARM::VST4q32oddPseudo_UPD, ARM::VST4q32_UPD, false, true, true, OddDblSpc, 4, 2 ,true},
507 { ARM::VST4q8Pseudo_UPD, ARM::VST4q8_UPD, false, true, true, EvenDblSpc, 4, 8 ,true},
508 { ARM::VST4q8oddPseudo, ARM::VST4q8, false, false, false, OddDblSpc, 4, 8 ,true},
509 { ARM::VST4q8oddPseudo_UPD, ARM::VST4q8_UPD, false, true, true, OddDblSpc, 4, 8 ,true}
510 };
511 
512 /// LookupNEONLdSt - Search the NEONLdStTable for information about a NEON
513 /// load or store pseudo instruction.
514 static const NEONLdStTableEntry *LookupNEONLdSt(unsigned Opcode) {
515 #ifndef NDEBUG
516  // Make sure the table is sorted.
517  static std::atomic<bool> TableChecked(false);
518  if (!TableChecked.load(std::memory_order_relaxed)) {
519  assert(llvm::is_sorted(NEONLdStTable) && "NEONLdStTable is not sorted!");
520  TableChecked.store(true, std::memory_order_relaxed);
521  }
522 #endif
523 
524  auto I = llvm::lower_bound(NEONLdStTable, Opcode);
525  if (I != std::end(NEONLdStTable) && I->PseudoOpc == Opcode)
526  return I;
527  return nullptr;
528 }
529 
530 /// GetDSubRegs - Get 4 D subregisters of a Q, QQ, or QQQQ register,
531 /// corresponding to the specified register spacing. Not all of the results
532 /// are necessarily valid, e.g., a Q register only has 2 D subregisters.
533 static void GetDSubRegs(unsigned Reg, NEONRegSpacing RegSpc,
534  const TargetRegisterInfo *TRI, unsigned &D0,
535  unsigned &D1, unsigned &D2, unsigned &D3) {
536  if (RegSpc == SingleSpc || RegSpc == SingleLowSpc) {
537  D0 = TRI->getSubReg(Reg, ARM::dsub_0);
538  D1 = TRI->getSubReg(Reg, ARM::dsub_1);
539  D2 = TRI->getSubReg(Reg, ARM::dsub_2);
540  D3 = TRI->getSubReg(Reg, ARM::dsub_3);
541  } else if (RegSpc == SingleHighQSpc) {
542  D0 = TRI->getSubReg(Reg, ARM::dsub_4);
543  D1 = TRI->getSubReg(Reg, ARM::dsub_5);
544  D2 = TRI->getSubReg(Reg, ARM::dsub_6);
545  D3 = TRI->getSubReg(Reg, ARM::dsub_7);
546  } else if (RegSpc == SingleHighTSpc) {
547  D0 = TRI->getSubReg(Reg, ARM::dsub_3);
548  D1 = TRI->getSubReg(Reg, ARM::dsub_4);
549  D2 = TRI->getSubReg(Reg, ARM::dsub_5);
550  D3 = TRI->getSubReg(Reg, ARM::dsub_6);
551  } else if (RegSpc == EvenDblSpc) {
552  D0 = TRI->getSubReg(Reg, ARM::dsub_0);
553  D1 = TRI->getSubReg(Reg, ARM::dsub_2);
554  D2 = TRI->getSubReg(Reg, ARM::dsub_4);
555  D3 = TRI->getSubReg(Reg, ARM::dsub_6);
556  } else {
557  assert(RegSpc == OddDblSpc && "unknown register spacing");
558  D0 = TRI->getSubReg(Reg, ARM::dsub_1);
559  D1 = TRI->getSubReg(Reg, ARM::dsub_3);
560  D2 = TRI->getSubReg(Reg, ARM::dsub_5);
561  D3 = TRI->getSubReg(Reg, ARM::dsub_7);
562  }
563 }
564 
565 /// ExpandVLD - Translate VLD pseudo instructions with Q, QQ or QQQQ register
566 /// operands to real VLD instructions with D register operands.
567 void ARMExpandPseudo::ExpandVLD(MachineBasicBlock::iterator &MBBI) {
568  MachineInstr &MI = *MBBI;
569  MachineBasicBlock &MBB = *MI.getParent();
570  LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
571 
572  const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode());
573  assert(TableEntry && TableEntry->IsLoad && "NEONLdStTable lookup failed");
574  NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
575  unsigned NumRegs = TableEntry->NumRegs;
576 
577  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
578  TII->get(TableEntry->RealOpc));
579  unsigned OpIdx = 0;
580 
581  bool DstIsDead = MI.getOperand(OpIdx).isDead();
582  Register DstReg = MI.getOperand(OpIdx++).getReg();
583 
584  bool IsVLD2DUP = TableEntry->RealOpc == ARM::VLD2DUPd8x2 ||
585  TableEntry->RealOpc == ARM::VLD2DUPd16x2 ||
586  TableEntry->RealOpc == ARM::VLD2DUPd32x2 ||
587  TableEntry->RealOpc == ARM::VLD2DUPd8x2wb_fixed ||
588  TableEntry->RealOpc == ARM::VLD2DUPd16x2wb_fixed ||
589  TableEntry->RealOpc == ARM::VLD2DUPd32x2wb_fixed ||
590  TableEntry->RealOpc == ARM::VLD2DUPd8x2wb_register ||
591  TableEntry->RealOpc == ARM::VLD2DUPd16x2wb_register ||
592  TableEntry->RealOpc == ARM::VLD2DUPd32x2wb_register;
593 
594  if (IsVLD2DUP) {
595  unsigned SubRegIndex;
596  if (RegSpc == EvenDblSpc) {
597  SubRegIndex = ARM::dsub_0;
598  } else {
599  assert(RegSpc == OddDblSpc && "Unexpected spacing!");
600  SubRegIndex = ARM::dsub_1;
601  }
602  Register SubReg = TRI->getSubReg(DstReg, SubRegIndex);
603  unsigned DstRegPair = TRI->getMatchingSuperReg(SubReg, ARM::dsub_0,
604  &ARM::DPairSpcRegClass);
605  MIB.addReg(DstRegPair, RegState::Define | getDeadRegState(DstIsDead));
606  } else {
607  unsigned D0, D1, D2, D3;
608  GetDSubRegs(DstReg, RegSpc, TRI, D0, D1, D2, D3);
609  MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead));
610  if (NumRegs > 1 && TableEntry->copyAllListRegs)
611  MIB.addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
612  if (NumRegs > 2 && TableEntry->copyAllListRegs)
613  MIB.addReg(D2, RegState::Define | getDeadRegState(DstIsDead));
614  if (NumRegs > 3 && TableEntry->copyAllListRegs)
615  MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead));
616  }
617 
618  if (TableEntry->isUpdating)
619  MIB.add(MI.getOperand(OpIdx++));
620 
621  // Copy the addrmode6 operands.
622  MIB.add(MI.getOperand(OpIdx++));
623  MIB.add(MI.getOperand(OpIdx++));
624 
625  // Copy the am6offset operand.
626  if (TableEntry->hasWritebackOperand) {
627  // TODO: The writing-back pseudo instructions we translate here are all
628  // defined to take am6offset nodes that are capable to represent both fixed
629  // and register forms. Some real instructions, however, do not rely on
630  // am6offset and have separate definitions for such forms. When this is the
631  // case, fixed forms do not take any offset nodes, so here we skip them for
632  // such instructions. Once all real and pseudo writing-back instructions are
633  // rewritten without use of am6offset nodes, this code will go away.
634  const MachineOperand &AM6Offset = MI.getOperand(OpIdx++);
635  if (TableEntry->RealOpc == ARM::VLD1d8Qwb_fixed ||
636  TableEntry->RealOpc == ARM::VLD1d16Qwb_fixed ||
637  TableEntry->RealOpc == ARM::VLD1d32Qwb_fixed ||
638  TableEntry->RealOpc == ARM::VLD1d64Qwb_fixed ||
639  TableEntry->RealOpc == ARM::VLD1d8Twb_fixed ||
640  TableEntry->RealOpc == ARM::VLD1d16Twb_fixed ||
641  TableEntry->RealOpc == ARM::VLD1d32Twb_fixed ||
642  TableEntry->RealOpc == ARM::VLD1d64Twb_fixed ||
643  TableEntry->RealOpc == ARM::VLD2DUPd8x2wb_fixed ||
644  TableEntry->RealOpc == ARM::VLD2DUPd16x2wb_fixed ||
645  TableEntry->RealOpc == ARM::VLD2DUPd32x2wb_fixed) {
646  assert(AM6Offset.getReg() == 0 &&
647  "A fixed writing-back pseudo instruction provides an offset "
648  "register!");
649  } else {
650  MIB.add(AM6Offset);
651  }
652  }
653 
654  // For an instruction writing double-spaced subregs, the pseudo instruction
655  // has an extra operand that is a use of the super-register. Record the
656  // operand index and skip over it.
657  unsigned SrcOpIdx = 0;
658  if (!IsVLD2DUP) {
659  if (RegSpc == EvenDblSpc || RegSpc == OddDblSpc ||
660  RegSpc == SingleLowSpc || RegSpc == SingleHighQSpc ||
661  RegSpc == SingleHighTSpc)
662  SrcOpIdx = OpIdx++;
663  }
664 
665  // Copy the predicate operands.
666  MIB.add(MI.getOperand(OpIdx++));
667  MIB.add(MI.getOperand(OpIdx++));
668 
669  // Copy the super-register source operand used for double-spaced subregs over
670  // to the new instruction as an implicit operand.
671  if (SrcOpIdx != 0) {
672  MachineOperand MO = MI.getOperand(SrcOpIdx);
673  MO.setImplicit(true);
674  MIB.add(MO);
675  }
676  // Add an implicit def for the super-register.
677  MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
678  TransferImpOps(MI, MIB, MIB);
679 
680  // Transfer memoperands.
681  MIB.cloneMemRefs(MI);
682  MI.eraseFromParent();
683  LLVM_DEBUG(dbgs() << "To: "; MIB.getInstr()->dump(););
684 }
685 
686 /// ExpandVST - Translate VST pseudo instructions with Q, QQ or QQQQ register
687 /// operands to real VST instructions with D register operands.
688 void ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator &MBBI) {
689  MachineInstr &MI = *MBBI;
690  MachineBasicBlock &MBB = *MI.getParent();
691  LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
692 
693  const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode());
694  assert(TableEntry && !TableEntry->IsLoad && "NEONLdStTable lookup failed");
695  NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
696  unsigned NumRegs = TableEntry->NumRegs;
697 
698  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
699  TII->get(TableEntry->RealOpc));
700  unsigned OpIdx = 0;
701  if (TableEntry->isUpdating)
702  MIB.add(MI.getOperand(OpIdx++));
703 
704  // Copy the addrmode6 operands.
705  MIB.add(MI.getOperand(OpIdx++));
706  MIB.add(MI.getOperand(OpIdx++));
707 
708  if (TableEntry->hasWritebackOperand) {
709  // TODO: The writing-back pseudo instructions we translate here are all
710  // defined to take am6offset nodes that are capable to represent both fixed
711  // and register forms. Some real instructions, however, do not rely on
712  // am6offset and have separate definitions for such forms. When this is the
713  // case, fixed forms do not take any offset nodes, so here we skip them for
714  // such instructions. Once all real and pseudo writing-back instructions are
715  // rewritten without use of am6offset nodes, this code will go away.
716  const MachineOperand &AM6Offset = MI.getOperand(OpIdx++);
717  if (TableEntry->RealOpc == ARM::VST1d8Qwb_fixed ||
718  TableEntry->RealOpc == ARM::VST1d16Qwb_fixed ||
719  TableEntry->RealOpc == ARM::VST1d32Qwb_fixed ||
720  TableEntry->RealOpc == ARM::VST1d64Qwb_fixed ||
721  TableEntry->RealOpc == ARM::VST1d8Twb_fixed ||
722  TableEntry->RealOpc == ARM::VST1d16Twb_fixed ||
723  TableEntry->RealOpc == ARM::VST1d32Twb_fixed ||
724  TableEntry->RealOpc == ARM::VST1d64Twb_fixed) {
725  assert(AM6Offset.getReg() == 0 &&
726  "A fixed writing-back pseudo instruction provides an offset "
727  "register!");
728  } else {
729  MIB.add(AM6Offset);
730  }
731  }
732 
733  bool SrcIsKill = MI.getOperand(OpIdx).isKill();
734  bool SrcIsUndef = MI.getOperand(OpIdx).isUndef();
735  Register SrcReg = MI.getOperand(OpIdx++).getReg();
736  unsigned D0, D1, D2, D3;
737  GetDSubRegs(SrcReg, RegSpc, TRI, D0, D1, D2, D3);
738  MIB.addReg(D0, getUndefRegState(SrcIsUndef));
739  if (NumRegs > 1 && TableEntry->copyAllListRegs)
740  MIB.addReg(D1, getUndefRegState(SrcIsUndef));
741  if (NumRegs > 2 && TableEntry->copyAllListRegs)
742  MIB.addReg(D2, getUndefRegState(SrcIsUndef));
743  if (NumRegs > 3 && TableEntry->copyAllListRegs)
744  MIB.addReg(D3, getUndefRegState(SrcIsUndef));
745 
746  // Copy the predicate operands.
747  MIB.add(MI.getOperand(OpIdx++));
748  MIB.add(MI.getOperand(OpIdx++));
749 
750  if (SrcIsKill && !SrcIsUndef) // Add an implicit kill for the super-reg.
751  MIB->addRegisterKilled(SrcReg, TRI, true);
752  else if (!SrcIsUndef)
753  MIB.addReg(SrcReg, RegState::Implicit); // Add implicit uses for src reg.
754  TransferImpOps(MI, MIB, MIB);
755 
756  // Transfer memoperands.
757  MIB.cloneMemRefs(MI);
758  MI.eraseFromParent();
759  LLVM_DEBUG(dbgs() << "To: "; MIB.getInstr()->dump(););
760 }
761 
762 /// ExpandLaneOp - Translate VLD*LN and VST*LN instructions with Q, QQ or QQQQ
763 /// register operands to real instructions with D register operands.
764 void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator &MBBI) {
765  MachineInstr &MI = *MBBI;
766  MachineBasicBlock &MBB = *MI.getParent();
767  LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
768 
769  const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode());
770  assert(TableEntry && "NEONLdStTable lookup failed");
771  NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
772  unsigned NumRegs = TableEntry->NumRegs;
773  unsigned RegElts = TableEntry->RegElts;
774 
775  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
776  TII->get(TableEntry->RealOpc));
777  unsigned OpIdx = 0;
778  // The lane operand is always the 3rd from last operand, before the 2
779  // predicate operands.
780  unsigned Lane = MI.getOperand(MI.getDesc().getNumOperands() - 3).getImm();
781 
782  // Adjust the lane and spacing as needed for Q registers.
783  assert(RegSpc != OddDblSpc && "unexpected register spacing for VLD/VST-lane");
784  if (RegSpc == EvenDblSpc && Lane >= RegElts) {
785  RegSpc = OddDblSpc;
786  Lane -= RegElts;
787  }
788  assert(Lane < RegElts && "out of range lane for VLD/VST-lane");
789 
790  unsigned D0 = 0, D1 = 0, D2 = 0, D3 = 0;
791  unsigned DstReg = 0;
792  bool DstIsDead = false;
793  if (TableEntry->IsLoad) {
794  DstIsDead = MI.getOperand(OpIdx).isDead();
795  DstReg = MI.getOperand(OpIdx++).getReg();
796  GetDSubRegs(DstReg, RegSpc, TRI, D0, D1, D2, D3);
797  MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead));
798  if (NumRegs > 1)
799  MIB.addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
800  if (NumRegs > 2)
801  MIB.addReg(D2, RegState::Define | getDeadRegState(DstIsDead));
802  if (NumRegs > 3)
803  MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead));
804  }
805 
806  if (TableEntry->isUpdating)
807  MIB.add(MI.getOperand(OpIdx++));
808 
809  // Copy the addrmode6 operands.
810  MIB.add(MI.getOperand(OpIdx++));
811  MIB.add(MI.getOperand(OpIdx++));
812  // Copy the am6offset operand.
813  if (TableEntry->hasWritebackOperand)
814  MIB.add(MI.getOperand(OpIdx++));
815 
816  // Grab the super-register source.
817  MachineOperand MO = MI.getOperand(OpIdx++);
818  if (!TableEntry->IsLoad)
819  GetDSubRegs(MO.getReg(), RegSpc, TRI, D0, D1, D2, D3);
820 
821  // Add the subregs as sources of the new instruction.
822  unsigned SrcFlags = (getUndefRegState(MO.isUndef()) |
823  getKillRegState(MO.isKill()));
824  MIB.addReg(D0, SrcFlags);
825  if (NumRegs > 1)
826  MIB.addReg(D1, SrcFlags);
827  if (NumRegs > 2)
828  MIB.addReg(D2, SrcFlags);
829  if (NumRegs > 3)
830  MIB.addReg(D3, SrcFlags);
831 
832  // Add the lane number operand.
833  MIB.addImm(Lane);
834  OpIdx += 1;
835 
836  // Copy the predicate operands.
837  MIB.add(MI.getOperand(OpIdx++));
838  MIB.add(MI.getOperand(OpIdx++));
839 
840  // Copy the super-register source to be an implicit source.
841  MO.setImplicit(true);
842  MIB.add(MO);
843  if (TableEntry->IsLoad)
844  // Add an implicit def for the super-register.
845  MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
846  TransferImpOps(MI, MIB, MIB);
847  // Transfer memoperands.
848  MIB.cloneMemRefs(MI);
849  MI.eraseFromParent();
850 }
851 
852 /// ExpandVTBL - Translate VTBL and VTBX pseudo instructions with Q or QQ
853 /// register operands to real instructions with D register operands.
854 void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator &MBBI,
855  unsigned Opc, bool IsExt) {
856  MachineInstr &MI = *MBBI;
857  MachineBasicBlock &MBB = *MI.getParent();
858  LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
859 
860  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc));
861  unsigned OpIdx = 0;
862 
863  // Transfer the destination register operand.
864  MIB.add(MI.getOperand(OpIdx++));
865  if (IsExt) {
866  MachineOperand VdSrc(MI.getOperand(OpIdx++));
867  MIB.add(VdSrc);
868  }
869 
870  bool SrcIsKill = MI.getOperand(OpIdx).isKill();
871  Register SrcReg = MI.getOperand(OpIdx++).getReg();
872  unsigned D0, D1, D2, D3;
873  GetDSubRegs(SrcReg, SingleSpc, TRI, D0, D1, D2, D3);
874  MIB.addReg(D0);
875 
876  // Copy the other source register operand.
877  MachineOperand VmSrc(MI.getOperand(OpIdx++));
878  MIB.add(VmSrc);
879 
880  // Copy the predicate operands.
881  MIB.add(MI.getOperand(OpIdx++));
882  MIB.add(MI.getOperand(OpIdx++));
883 
884  // Add an implicit kill and use for the super-reg.
885  MIB.addReg(SrcReg, RegState::Implicit | getKillRegState(SrcIsKill));
886  TransferImpOps(MI, MIB, MIB);
887  MI.eraseFromParent();
888  LLVM_DEBUG(dbgs() << "To: "; MIB.getInstr()->dump(););
889 }
890 
891 void ARMExpandPseudo::ExpandMQQPRLoadStore(MachineBasicBlock::iterator &MBBI) {
892  MachineInstr &MI = *MBBI;
893  MachineBasicBlock &MBB = *MI.getParent();
894  unsigned NewOpc =
895  MI.getOpcode() == ARM::MQQPRStore || MI.getOpcode() == ARM::MQQQQPRStore
896  ? ARM::VSTMDIA
897  : ARM::VLDMDIA;
898  MachineInstrBuilder MIB =
899  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
900 
901  unsigned Flags = getKillRegState(MI.getOperand(0).isKill()) |
902  getDefRegState(MI.getOperand(0).isDef());
903  Register SrcReg = MI.getOperand(0).getReg();
904 
905  // Copy the destination register.
906  MIB.add(MI.getOperand(1));
907  MIB.add(predOps(ARMCC::AL));
908  MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_0), Flags);
909  MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_1), Flags);
910  MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_2), Flags);
911  MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_3), Flags);
912  if (MI.getOpcode() == ARM::MQQQQPRStore ||
913  MI.getOpcode() == ARM::MQQQQPRLoad) {
914  MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_4), Flags);
915  MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_5), Flags);
916  MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_6), Flags);
917  MIB.addReg(TRI->getSubReg(SrcReg, ARM::dsub_7), Flags);
918  }
919 
920  if (NewOpc == ARM::VSTMDIA)
921  MIB.addReg(SrcReg, RegState::Implicit);
922 
923  TransferImpOps(MI, MIB, MIB);
924  MIB.cloneMemRefs(MI);
925  MI.eraseFromParent();
926 }
927 
928 static bool IsAnAddressOperand(const MachineOperand &MO) {
929  // This check is overly conservative. Unless we are certain that the machine
930  // operand is not a symbol reference, we return that it is a symbol reference.
931  // This is important as the load pair may not be split up Windows.
932  switch (MO.getType()) {
938  return false;
940  return true;
942  return false;
949  return true;
952  return false;
955  return true;
957  return false;
960  llvm_unreachable("should not exist post-isel");
961  }
962  llvm_unreachable("unhandled machine operand type");
963 }
964 
966  MachineOperand NewMO = MO;
967  NewMO.setImplicit();
968  return NewMO;
969 }
970 
971 void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
973  MachineInstr &MI = *MBBI;
974  unsigned Opcode = MI.getOpcode();
975  Register PredReg;
976  ARMCC::CondCodes Pred = getInstrPredicate(MI, PredReg);
977  Register DstReg = MI.getOperand(0).getReg();
978  bool DstIsDead = MI.getOperand(0).isDead();
979  bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
980  const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1);
981  bool RequiresBundling = STI->isTargetWindows() && IsAnAddressOperand(MO);
982  MachineInstrBuilder LO16, HI16;
983  LLVM_DEBUG(dbgs() << "Expanding: "; MI.dump());
984 
985  if (!STI->hasV6T2Ops() &&
986  (Opcode == ARM::MOVi32imm || Opcode == ARM::MOVCCi32imm)) {
987  // FIXME Windows CE supports older ARM CPUs
988  assert(!STI->isTargetWindows() && "Windows on ARM requires ARMv7+");
989 
990  assert (MO.isImm() && "MOVi32imm w/ non-immediate source operand!");
991  unsigned ImmVal = (unsigned)MO.getImm();
992  unsigned SOImmValV1 = 0, SOImmValV2 = 0;
993 
994  if (ARM_AM::isSOImmTwoPartVal(ImmVal)) { // Expand into a movi + orr.
995  LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi), DstReg);
996  HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ORRri))
997  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
998  .addReg(DstReg);
999  SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
1000  SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
1001  } else { // Expand into a mvn + sub.
1002  LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MVNi), DstReg);
1003  HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri))
1004  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1005  .addReg(DstReg);
1006  SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(-ImmVal);
1007  SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(-ImmVal);
1008  SOImmValV1 = ~(-SOImmValV1);
1009  }
1010 
1011  unsigned MIFlags = MI.getFlags();
1012  LO16 = LO16.addImm(SOImmValV1);
1013  HI16 = HI16.addImm(SOImmValV2);
1014  LO16.cloneMemRefs(MI);
1015  HI16.cloneMemRefs(MI);
1016  LO16.setMIFlags(MIFlags);
1017  HI16.setMIFlags(MIFlags);
1018  LO16.addImm(Pred).addReg(PredReg).add(condCodeOp());
1019  HI16.addImm(Pred).addReg(PredReg).add(condCodeOp());
1020  if (isCC)
1021  LO16.add(makeImplicit(MI.getOperand(1)));
1022  TransferImpOps(MI, LO16, HI16);
1023  MI.eraseFromParent();
1024  return;
1025  }
1026 
1027  unsigned LO16Opc = 0;
1028  unsigned HI16Opc = 0;
1029  unsigned MIFlags = MI.getFlags();
1030  if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) {
1031  LO16Opc = ARM::t2MOVi16;
1032  HI16Opc = ARM::t2MOVTi16;
1033  } else {
1034  LO16Opc = ARM::MOVi16;
1035  HI16Opc = ARM::MOVTi16;
1036  }
1037 
1038  LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg);
1039  HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc))
1040  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
1041  .addReg(DstReg);
1042 
1043  LO16.setMIFlags(MIFlags);
1044  HI16.setMIFlags(MIFlags);
1045 
1046  switch (MO.getType()) {
1048  unsigned Imm = MO.getImm();
1049  unsigned Lo16 = Imm & 0xffff;
1050  unsigned Hi16 = (Imm >> 16) & 0xffff;
1051  LO16 = LO16.addImm(Lo16);
1052  HI16 = HI16.addImm(Hi16);
1053  break;
1054  }
1056  const char *ES = MO.getSymbolName();
1057  unsigned TF = MO.getTargetFlags();
1058  LO16 = LO16.addExternalSymbol(ES, TF | ARMII::MO_LO16);
1059  HI16 = HI16.addExternalSymbol(ES, TF | ARMII::MO_HI16);
1060  break;
1061  }
1062  default: {
1063  const GlobalValue *GV = MO.getGlobal();
1064  unsigned TF = MO.getTargetFlags();
1065  LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
1066  HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
1067  break;
1068  }
1069  }
1070 
1071  LO16.cloneMemRefs(MI);
1072  HI16.cloneMemRefs(MI);
1073  LO16.addImm(Pred).addReg(PredReg);
1074  HI16.addImm(Pred).addReg(PredReg);
1075 
1076  if (RequiresBundling)
1078 
1079  if (isCC)
1080  LO16.add(makeImplicit(MI.getOperand(1)));
1081  TransferImpOps(MI, LO16, HI16);
1082  MI.eraseFromParent();
1083  LLVM_DEBUG(dbgs() << "To: "; LO16.getInstr()->dump(););
1084  LLVM_DEBUG(dbgs() << "And: "; HI16.getInstr()->dump(););
1085 }
1086 
1087 // The size of the area, accessed by that VLSTM/VLLDM
1088 // S0-S31 + FPSCR + 8 more bytes (VPR + pad, or just pad)
1089 static const int CMSE_FP_SAVE_SIZE = 136;
1090 
1092  const std::initializer_list<unsigned> &Regs,
1093  SmallVectorImpl<unsigned> &ClearRegs) {
1094  SmallVector<unsigned, 4> OpRegs;
1095  for (const MachineOperand &Op : MI.operands()) {
1096  if (!Op.isReg() || !Op.isUse())
1097  continue;
1098  OpRegs.push_back(Op.getReg());
1099  }
1100  llvm::sort(OpRegs);
1101 
1102  std::set_difference(Regs.begin(), Regs.end(), OpRegs.begin(), OpRegs.end(),
1103  std::back_inserter(ClearRegs));
1104 }
1105 
1106 void ARMExpandPseudo::CMSEClearGPRegs(
1108  const DebugLoc &DL, const SmallVectorImpl<unsigned> &ClearRegs,
1109  unsigned ClobberReg) {
1110 
1111  if (STI->hasV8_1MMainlineOps()) {
1112  // Clear the registers using the CLRM instruction.
1113  MachineInstrBuilder CLRM =
1114  BuildMI(MBB, MBBI, DL, TII->get(ARM::t2CLRM)).add(predOps(ARMCC::AL));
1115  for (unsigned R : ClearRegs)
1116  CLRM.addReg(R, RegState::Define);
1117  CLRM.addReg(ARM::APSR, RegState::Define);
1118  CLRM.addReg(ARM::CPSR, RegState::Define | RegState::Implicit);
1119  } else {
1120  // Clear the registers and flags by copying ClobberReg into them.
1121  // (Baseline can't do a high register clear in one instruction).
1122  for (unsigned Reg : ClearRegs) {
1123  if (Reg == ClobberReg)
1124  continue;
1125  BuildMI(MBB, MBBI, DL, TII->get(ARM::tMOVr), Reg)
1126  .addReg(ClobberReg)
1127  .add(predOps(ARMCC::AL));
1128  }
1129 
1130  BuildMI(MBB, MBBI, DL, TII->get(ARM::t2MSR_M))
1131  .addImm(STI->hasDSP() ? 0xc00 : 0x800)
1132  .addReg(ClobberReg)
1133  .add(predOps(ARMCC::AL));
1134  }
1135 }
1136 
1137 // Find which FP registers need to be cleared. The parameter `ClearRegs` is
1138 // initialised with all elements set to true, and this function resets all the
1139 // bits, which correspond to register uses. Returns true if any floating point
1140 // register is defined, false otherwise.
1142  BitVector &ClearRegs) {
1143  bool DefFP = false;
1144  for (const MachineOperand &Op : MI.operands()) {
1145  if (!Op.isReg())
1146  continue;
1147 
1148  unsigned Reg = Op.getReg();
1149  if (Op.isDef()) {
1150  if ((Reg >= ARM::Q0 && Reg <= ARM::Q7) ||
1151  (Reg >= ARM::D0 && Reg <= ARM::D15) ||
1152  (Reg >= ARM::S0 && Reg <= ARM::S31))
1153  DefFP = true;
1154  continue;
1155  }
1156 
1157  if (Reg >= ARM::Q0 && Reg <= ARM::Q7) {
1158  int R = Reg - ARM::Q0;
1159  ClearRegs.reset(R * 4, (R + 1) * 4);
1160  } else if (Reg >= ARM::D0 && Reg <= ARM::D15) {
1161  int R = Reg - ARM::D0;
1162  ClearRegs.reset(R * 2, (R + 1) * 2);
1163  } else if (Reg >= ARM::S0 && Reg <= ARM::S31) {
1164  ClearRegs[Reg - ARM::S0] = false;
1165  }
1166  }
1167  return DefFP;
1168 }
1169 
1171 ARMExpandPseudo::CMSEClearFPRegs(MachineBasicBlock &MBB,
1173  BitVector ClearRegs(16, true);
1174  (void)determineFPRegsToClear(*MBBI, ClearRegs);
1175 
1176  if (STI->hasV8_1MMainlineOps())
1177  return CMSEClearFPRegsV81(MBB, MBBI, ClearRegs);
1178  else
1179  return CMSEClearFPRegsV8(MBB, MBBI, ClearRegs);
1180 }
1181 
1182 // Clear the FP registers for v8.0-M, by copying over the content
1183 // of LR. Uses R12 as a scratch register.
1185 ARMExpandPseudo::CMSEClearFPRegsV8(MachineBasicBlock &MBB,
1187  const BitVector &ClearRegs) {
1188  if (!STI->hasFPRegs())
1189  return MBB;
1190 
1191  auto &RetI = *MBBI;
1192  const DebugLoc &DL = RetI.getDebugLoc();
1193 
1194  // If optimising for minimum size, clear FP registers unconditionally.
1195  // Otherwise, check the CONTROL.SFPA (Secure Floating-Point Active) bit and
1196  // don't clear them if they belong to the non-secure state.
1197  MachineBasicBlock *ClearBB, *DoneBB;
1198  if (STI->hasMinSize()) {
1199  ClearBB = DoneBB = &MBB;
1200  } else {
1201  MachineFunction *MF = MBB.getParent();
1202  ClearBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
1203  DoneBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
1204 
1205  MF->insert(++MBB.getIterator(), ClearBB);
1206  MF->insert(++ClearBB->getIterator(), DoneBB);
1207 
1208  DoneBB->splice(DoneBB->end(), &MBB, MBBI, MBB.end());
1209  DoneBB->transferSuccessors(&MBB);
1210  MBB.addSuccessor(ClearBB);
1211  MBB.addSuccessor(DoneBB);
1212  ClearBB->addSuccessor(DoneBB);
1213 
1214  // At the new basic blocks we need to have live-in the registers, used
1215  // for the return value as well as LR, used to clear registers.
1216  for (const MachineOperand &Op : RetI.operands()) {
1217  if (!Op.isReg())
1218  continue;
1219  Register Reg = Op.getReg();
1220  if (Reg == ARM::NoRegister || Reg == ARM::LR)
1221  continue;
1222  assert(Register::isPhysicalRegister(Reg) && "Unallocated register");
1223  ClearBB->addLiveIn(Reg);
1224  DoneBB->addLiveIn(Reg);
1225  }
1226  ClearBB->addLiveIn(ARM::LR);
1227  DoneBB->addLiveIn(ARM::LR);
1228 
1229  // Read the CONTROL register.
1230  BuildMI(MBB, MBB.end(), DL, TII->get(ARM::t2MRS_M), ARM::R12)
1231  .addImm(20)
1232  .add(predOps(ARMCC::AL));
1233  // Check bit 3 (SFPA).
1234  BuildMI(MBB, MBB.end(), DL, TII->get(ARM::t2TSTri))
1235  .addReg(ARM::R12)
1236  .addImm(8)
1237  .add(predOps(ARMCC::AL));
1238  // If SFPA is clear, jump over ClearBB to DoneBB.
1239  BuildMI(MBB, MBB.end(), DL, TII->get(ARM::tBcc))
1240  .addMBB(DoneBB)
1241  .addImm(ARMCC::EQ)
1242  .addReg(ARM::CPSR, RegState::Kill);
1243  }
1244 
1245  // Emit the clearing sequence
1246  for (unsigned D = 0; D < 8; D++) {
1247  // Attempt to clear as double
1248  if (ClearRegs[D * 2 + 0] && ClearRegs[D * 2 + 1]) {
1249  unsigned Reg = ARM::D0 + D;
1250  BuildMI(ClearBB, DL, TII->get(ARM::VMOVDRR), Reg)
1251  .addReg(ARM::LR)
1252  .addReg(ARM::LR)
1253  .add(predOps(ARMCC::AL));
1254  } else {
1255  // Clear first part as single
1256  if (ClearRegs[D * 2 + 0]) {
1257  unsigned Reg = ARM::S0 + D * 2;
1258  BuildMI(ClearBB, DL, TII->get(ARM::VMOVSR), Reg)
1259  .addReg(ARM::LR)
1260  .add(predOps(ARMCC::AL));
1261  }
1262  // Clear second part as single
1263  if (ClearRegs[D * 2 + 1]) {
1264  unsigned Reg = ARM::S0 + D * 2 + 1;
1265  BuildMI(ClearBB, DL, TII->get(ARM::VMOVSR), Reg)
1266  .addReg(ARM::LR)
1267  .add(predOps(ARMCC::AL));
1268  }
1269  }
1270  }
1271 
1272  // Clear FPSCR bits 0-4, 7, 28-31
1273  // The other bits are program global according to the AAPCS
1274  BuildMI(ClearBB, DL, TII->get(ARM::VMRS), ARM::R12)
1275  .add(predOps(ARMCC::AL));
1276  BuildMI(ClearBB, DL, TII->get(ARM::t2BICri), ARM::R12)
1277  .addReg(ARM::R12)
1278  .addImm(0x0000009F)
1279  .add(predOps(ARMCC::AL))
1280  .add(condCodeOp());
1281  BuildMI(ClearBB, DL, TII->get(ARM::t2BICri), ARM::R12)
1282  .addReg(ARM::R12)
1283  .addImm(0xF0000000)
1284  .add(predOps(ARMCC::AL))
1285  .add(condCodeOp());
1286  BuildMI(ClearBB, DL, TII->get(ARM::VMSR))
1287  .addReg(ARM::R12)
1288  .add(predOps(ARMCC::AL));
1289 
1290  return *DoneBB;
1291 }
1292 
1294 ARMExpandPseudo::CMSEClearFPRegsV81(MachineBasicBlock &MBB,
1296  const BitVector &ClearRegs) {
1297  auto &RetI = *MBBI;
1298 
1299  // Emit a sequence of VSCCLRM <sreglist> instructions, one instruction for
1300  // each contiguous sequence of S-registers.
1301  int Start = -1, End = -1;
1302  for (int S = 0, E = ClearRegs.size(); S != E; ++S) {
1303  if (ClearRegs[S] && S == End + 1) {
1304  End = S; // extend range
1305  continue;
1306  }
1307  // Emit current range.
1308  if (Start < End) {
1309  MachineInstrBuilder VSCCLRM =
1310  BuildMI(MBB, MBBI, RetI.getDebugLoc(), TII->get(ARM::VSCCLRMS))
1311  .add(predOps(ARMCC::AL));
1312  while (++Start <= End)
1313  VSCCLRM.addReg(ARM::S0 + Start, RegState::Define);
1314  VSCCLRM.addReg(ARM::VPR, RegState::Define);
1315  }
1316  Start = End = S;
1317  }
1318  // Emit last range.
1319  if (Start < End) {
1320  MachineInstrBuilder VSCCLRM =
1321  BuildMI(MBB, MBBI, RetI.getDebugLoc(), TII->get(ARM::VSCCLRMS))
1322  .add(predOps(ARMCC::AL));
1323  while (++Start <= End)
1324  VSCCLRM.addReg(ARM::S0 + Start, RegState::Define);
1325  VSCCLRM.addReg(ARM::VPR, RegState::Define);
1326  }
1327 
1328  return MBB;
1329 }
1330 
1331 void ARMExpandPseudo::CMSESaveClearFPRegs(
1333  const LivePhysRegs &LiveRegs, SmallVectorImpl<unsigned> &ScratchRegs) {
1334  if (STI->hasV8_1MMainlineOps())
1335  CMSESaveClearFPRegsV81(MBB, MBBI, DL, LiveRegs);
1336  else if (STI->hasV8MMainlineOps())
1337  CMSESaveClearFPRegsV8(MBB, MBBI, DL, LiveRegs, ScratchRegs);
1338 }
1339 
1340 // Save and clear FP registers if present
1341 void ARMExpandPseudo::CMSESaveClearFPRegsV8(
1343  const LivePhysRegs &LiveRegs, SmallVectorImpl<unsigned> &ScratchRegs) {
1344 
1345  // Store an available register for FPSCR clearing
1346  assert(!ScratchRegs.empty());
1347  unsigned SpareReg = ScratchRegs.front();
1348 
1349  // save space on stack for VLSTM
1350  BuildMI(MBB, MBBI, DL, TII->get(ARM::tSUBspi), ARM::SP)
1351  .addReg(ARM::SP)
1352  .addImm(CMSE_FP_SAVE_SIZE >> 2)
1353  .add(predOps(ARMCC::AL));
1354 
1355  // Use ScratchRegs to store the fp regs
1356  std::vector<std::tuple<unsigned, unsigned, unsigned>> ClearedFPRegs;
1357  std::vector<unsigned> NonclearedFPRegs;
1358  for (const MachineOperand &Op : MBBI->operands()) {
1359  if (Op.isReg() && Op.isUse()) {
1360  unsigned Reg = Op.getReg();
1361  assert(!ARM::DPRRegClass.contains(Reg) ||
1362  ARM::DPR_VFP2RegClass.contains(Reg));
1363  assert(!ARM::QPRRegClass.contains(Reg));
1364  if (ARM::DPR_VFP2RegClass.contains(Reg)) {
1365  if (ScratchRegs.size() >= 2) {
1366  unsigned SaveReg2 = ScratchRegs.pop_back_val();
1367  unsigned SaveReg1 = ScratchRegs.pop_back_val();
1368  ClearedFPRegs.emplace_back(Reg, SaveReg1, SaveReg2);
1369 
1370  // Save the fp register to the normal registers
1371  BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVRRD))
1372  .addReg(SaveReg1, RegState::Define)
1373  .addReg(SaveReg2, RegState::Define)
1374  .addReg(Reg)
1375  .add(predOps(ARMCC::AL));
1376  } else {
1377  NonclearedFPRegs.push_back(Reg);
1378  }
1379  } else if (ARM::SPRRegClass.contains(Reg)) {
1380  if (ScratchRegs.size() >= 1) {
1381  unsigned SaveReg = ScratchRegs.pop_back_val();
1382  ClearedFPRegs.emplace_back(Reg, SaveReg, 0);
1383 
1384  // Save the fp register to the normal registers
1385  BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVRS), SaveReg)
1386  .addReg(Reg)
1387  .add(predOps(ARMCC::AL));
1388  } else {
1389  NonclearedFPRegs.push_back(Reg);
1390  }
1391  }
1392  }
1393  }
1394 
1395  bool passesFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty());
1396 
1397  if (passesFPReg)
1398  assert(STI->hasFPRegs() && "Subtarget needs fpregs");
1399 
1400  // Lazy store all fp registers to the stack.
1401  // This executes as NOP in the absence of floating-point support.
1402  MachineInstrBuilder VLSTM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLSTM))
1403  .addReg(ARM::SP)
1404  .add(predOps(ARMCC::AL));
1405  for (auto R : {ARM::VPR, ARM::FPSCR, ARM::FPSCR_NZCV, ARM::Q0, ARM::Q1,
1406  ARM::Q2, ARM::Q3, ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7})
1407  VLSTM.addReg(R, RegState::Implicit |
1408  (LiveRegs.contains(R) ? 0 : RegState::Undef));
1409 
1410  // Restore all arguments
1411  for (const auto &Regs : ClearedFPRegs) {
1412  unsigned Reg, SaveReg1, SaveReg2;
1413  std::tie(Reg, SaveReg1, SaveReg2) = Regs;
1414  if (ARM::DPR_VFP2RegClass.contains(Reg))
1415  BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVDRR), Reg)
1416  .addReg(SaveReg1)
1417  .addReg(SaveReg2)
1418  .add(predOps(ARMCC::AL));
1419  else if (ARM::SPRRegClass.contains(Reg))
1420  BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVSR), Reg)
1421  .addReg(SaveReg1)
1422  .add(predOps(ARMCC::AL));
1423  }
1424 
1425  for (unsigned Reg : NonclearedFPRegs) {
1426  if (ARM::DPR_VFP2RegClass.contains(Reg)) {
1427  if (STI->isLittle()) {
1428  BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDRD), Reg)
1429  .addReg(ARM::SP)
1430  .addImm((Reg - ARM::D0) * 2)
1431  .add(predOps(ARMCC::AL));
1432  } else {
1433  // For big-endian targets we need to load the two subregisters of Reg
1434  // manually because VLDRD would load them in wrong order
1435  unsigned SReg0 = TRI->getSubReg(Reg, ARM::ssub_0);
1436  BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDRS), SReg0)
1437  .addReg(ARM::SP)
1438  .addImm((Reg - ARM::D0) * 2)
1439  .add(predOps(ARMCC::AL));
1440  BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDRS), SReg0 + 1)
1441  .addReg(ARM::SP)
1442  .addImm((Reg - ARM::D0) * 2 + 1)
1443  .add(predOps(ARMCC::AL));
1444  }
1445  } else if (ARM::SPRRegClass.contains(Reg)) {
1446  BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDRS), Reg)
1447  .addReg(ARM::SP)
1448  .addImm(Reg - ARM::S0)
1449  .add(predOps(ARMCC::AL));
1450  }
1451  }
1452  // restore FPSCR from stack and clear bits 0-4, 7, 28-31
1453  // The other bits are program global according to the AAPCS
1454  if (passesFPReg) {
1455  BuildMI(MBB, MBBI, DL, TII->get(ARM::t2LDRi8), SpareReg)
1456  .addReg(ARM::SP)
1457  .addImm(0x40)
1458  .add(predOps(ARMCC::AL));
1459  BuildMI(MBB, MBBI, DL, TII->get(ARM::t2BICri), SpareReg)
1460  .addReg(SpareReg)
1461  .addImm(0x0000009F)
1462  .add(predOps(ARMCC::AL))
1463  .add(condCodeOp());
1464  BuildMI(MBB, MBBI, DL, TII->get(ARM::t2BICri), SpareReg)
1465  .addReg(SpareReg)
1466  .addImm(0xF0000000)
1467  .add(predOps(ARMCC::AL))
1468  .add(condCodeOp());
1469  BuildMI(MBB, MBBI, DL, TII->get(ARM::VMSR))
1470  .addReg(SpareReg)
1471  .add(predOps(ARMCC::AL));
1472  // The ldr must happen after a floating point instruction. To prevent the
1473  // post-ra scheduler to mess with the order, we create a bundle.
1475  }
1476 }
1477 
1478 void ARMExpandPseudo::CMSESaveClearFPRegsV81(MachineBasicBlock &MBB,
1480  DebugLoc &DL,
1481  const LivePhysRegs &LiveRegs) {
1482  BitVector ClearRegs(32, true);
1483  bool DefFP = determineFPRegsToClear(*MBBI, ClearRegs);
1484 
1485  // If the instruction does not write to a FP register and no elements were
1486  // removed from the set, then no FP registers were used to pass
1487  // arguments/returns.
1488  if (!DefFP && ClearRegs.count() == ClearRegs.size()) {
1489  // save space on stack for VLSTM
1490  BuildMI(MBB, MBBI, DL, TII->get(ARM::tSUBspi), ARM::SP)
1491  .addReg(ARM::SP)
1492  .addImm(CMSE_FP_SAVE_SIZE >> 2)
1493  .add(predOps(ARMCC::AL));
1494 
1495  // Lazy store all FP registers to the stack
1496  MachineInstrBuilder VLSTM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLSTM))
1497  .addReg(ARM::SP)
1498  .add(predOps(ARMCC::AL));
1499  for (auto R : {ARM::VPR, ARM::FPSCR, ARM::FPSCR_NZCV, ARM::Q0, ARM::Q1,
1500  ARM::Q2, ARM::Q3, ARM::Q4, ARM::Q5, ARM::Q6, ARM::Q7})
1501  VLSTM.addReg(R, RegState::Implicit |
1502  (LiveRegs.contains(R) ? 0 : RegState::Undef));
1503  } else {
1504  // Push all the callee-saved registers (s16-s31).
1505  MachineInstrBuilder VPUSH =
1506  BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTMSDB_UPD), ARM::SP)
1507  .addReg(ARM::SP)
1508  .add(predOps(ARMCC::AL));
1509  for (int Reg = ARM::S16; Reg <= ARM::S31; ++Reg)
1510  VPUSH.addReg(Reg);
1511 
1512  // Clear FP registers with a VSCCLRM.
1513  (void)CMSEClearFPRegsV81(MBB, MBBI, ClearRegs);
1514 
1515  // Save floating-point context.
1516  BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTR_FPCXTS_pre), ARM::SP)
1517  .addReg(ARM::SP)
1518  .addImm(-8)
1519  .add(predOps(ARMCC::AL));
1520  }
1521 }
1522 
1523 // Restore FP registers if present
1524 void ARMExpandPseudo::CMSERestoreFPRegs(
1526  SmallVectorImpl<unsigned> &AvailableRegs) {
1527  if (STI->hasV8_1MMainlineOps())
1528  CMSERestoreFPRegsV81(MBB, MBBI, DL, AvailableRegs);
1529  else if (STI->hasV8MMainlineOps())
1530  CMSERestoreFPRegsV8(MBB, MBBI, DL, AvailableRegs);
1531 }
1532 
1533 void ARMExpandPseudo::CMSERestoreFPRegsV8(
1535  SmallVectorImpl<unsigned> &AvailableRegs) {
1536 
1537  // Keep a scratch register for the mitigation sequence.
1538  unsigned ScratchReg = ARM::NoRegister;
1539  if (STI->fixCMSE_CVE_2021_35465())
1540  ScratchReg = AvailableRegs.pop_back_val();
1541 
1542  // Use AvailableRegs to store the fp regs
1543  std::vector<std::tuple<unsigned, unsigned, unsigned>> ClearedFPRegs;
1544  std::vector<unsigned> NonclearedFPRegs;
1545  for (const MachineOperand &Op : MBBI->operands()) {
1546  if (Op.isReg() && Op.isDef()) {
1547  unsigned Reg = Op.getReg();
1548  assert(!ARM::DPRRegClass.contains(Reg) ||
1549  ARM::DPR_VFP2RegClass.contains(Reg));
1550  assert(!ARM::QPRRegClass.contains(Reg));
1551  if (ARM::DPR_VFP2RegClass.contains(Reg)) {
1552  if (AvailableRegs.size() >= 2) {
1553  unsigned SaveReg2 = AvailableRegs.pop_back_val();
1554  unsigned SaveReg1 = AvailableRegs.pop_back_val();
1555  ClearedFPRegs.emplace_back(Reg, SaveReg1, SaveReg2);
1556 
1557  // Save the fp register to the normal registers
1558  BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVRRD))
1559  .addReg(SaveReg1, RegState::Define)
1560  .addReg(SaveReg2, RegState::Define)
1561  .addReg(Reg)
1562  .add(predOps(ARMCC::AL));
1563  } else {
1564  NonclearedFPRegs.push_back(Reg);
1565  }
1566  } else if (ARM::SPRRegClass.contains(Reg)) {
1567  if (AvailableRegs.size() >= 1) {
1568  unsigned SaveReg = AvailableRegs.pop_back_val();
1569  ClearedFPRegs.emplace_back(Reg, SaveReg, 0);
1570 
1571  // Save the fp register to the normal registers
1572  BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVRS), SaveReg)
1573  .addReg(Reg)
1574  .add(predOps(ARMCC::AL));
1575  } else {
1576  NonclearedFPRegs.push_back(Reg);
1577  }
1578  }
1579  }
1580  }
1581 
1582  bool returnsFPReg = (!NonclearedFPRegs.empty() || !ClearedFPRegs.empty());
1583 
1584  if (returnsFPReg)
1585  assert(STI->hasFPRegs() && "Subtarget needs fpregs");
1586 
1587  // Push FP regs that cannot be restored via normal registers on the stack
1588  for (unsigned Reg : NonclearedFPRegs) {
1589  if (ARM::DPR_VFP2RegClass.contains(Reg))
1590  BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTRD))
1591  .addReg(Reg)
1592  .addReg(ARM::SP)
1593  .addImm((Reg - ARM::D0) * 2)
1594  .add(predOps(ARMCC::AL));
1595  else if (ARM::SPRRegClass.contains(Reg))
1596  BuildMI(MBB, MBBI, DL, TII->get(ARM::VSTRS))
1597  .addReg(Reg)
1598  .addReg(ARM::SP)
1599  .addImm(Reg - ARM::S0)
1600  .add(predOps(ARMCC::AL));
1601  }
1602 
1603  // Lazy load fp regs from stack.
1604  // This executes as NOP in the absence of floating-point support.
1605  MachineInstrBuilder VLLDM = BuildMI(MBB, MBBI, DL, TII->get(ARM::VLLDM))
1606  .addReg(ARM::SP)
1607  .add(predOps(ARMCC::AL));
1608 
1609  if (STI->fixCMSE_CVE_2021_35465()) {
1610  auto Bundler = MIBundleBuilder(MBB, VLLDM);
1611  // Read the CONTROL register.
1612  Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::t2MRS_M))
1613  .addReg(ScratchReg, RegState::Define)
1614  .addImm(20)
1615  .add(predOps(ARMCC::AL)));
1616  // Check bit 3 (SFPA).
1617  Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::t2TSTri))
1618  .addReg(ScratchReg)
1619  .addImm(8)
1620  .add(predOps(ARMCC::AL)));
1621  // Emit the IT block.
1622  Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::t2IT))
1623  .addImm(ARMCC::NE)
1624  .addImm(8));
1625  // If SFPA is clear jump over to VLLDM, otherwise execute an instruction
1626  // which has no functional effect apart from causing context creation:
1627  // vmovne s0, s0. In the absence of FPU we emit .inst.w 0xeeb00a40,
1628  // which is defined as NOP if not executed.
1629  if (STI->hasFPRegs())
1630  Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::VMOVS))
1631  .addReg(ARM::S0, RegState::Define)
1632  .addReg(ARM::S0, RegState::Undef)
1633  .add(predOps(ARMCC::NE)));
1634  else
1635  Bundler.append(BuildMI(*MBB.getParent(), DL, TII->get(ARM::INLINEASM))
1636  .addExternalSymbol(".inst.w 0xeeb00a40")
1638  finalizeBundle(MBB, Bundler.begin(), Bundler.end());
1639  }
1640 
1641  // Restore all FP registers via normal registers
1642  for (const auto &Regs : ClearedFPRegs) {
1643  unsigned Reg, SaveReg1, SaveReg2;
1644  std::tie(Reg, SaveReg1, SaveReg2) = Regs;
1645  if (ARM::DPR_VFP2RegClass.contains(Reg))
1646  BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVDRR), Reg)
1647  .addReg(SaveReg1)
1648  .addReg(SaveReg2)
1649  .add(predOps(ARMCC::AL));
1650  else if (ARM::SPRRegClass.contains(Reg))
1651  BuildMI(MBB, MBBI, DL, TII->get(ARM::VMOVSR), Reg)
1652  .addReg(SaveReg1)
1653  .add(predOps(ARMCC::AL));
1654  }
1655 
1656  // Pop the stack space
1657  BuildMI(MBB, MBBI, DL, TII->get(ARM::tADDspi), ARM::SP)
1658  .addReg(ARM::SP)
1659  .addImm(CMSE_FP_SAVE_SIZE >> 2)
1660  .add(predOps(ARMCC::AL));
1661 }
1662 
1663 static bool definesOrUsesFPReg(const MachineInstr &MI) {
1664  for (const MachineOperand &Op : MI.operands()) {
1665  if (!Op.isReg())
1666  continue;
1667  unsigned Reg = Op.getReg();
1668  if ((Reg >= ARM::Q0 && Reg <= ARM::Q7) ||
1669  (Reg >= ARM::D0 && Reg <= ARM::D15) ||
1670  (Reg >= ARM::S0 && Reg <= ARM::S31))
1671  return true;
1672  }
1673  return false;
1674 }
1675 
1676 void ARMExpandPseudo::CMSERestoreFPRegsV81(
1678  SmallVectorImpl<unsigned> &AvailableRegs) {
1679  if (!definesOrUsesFPReg(*MBBI)) {
1680  if (STI->fixCMSE_CVE_2021_35465()) {
1681  BuildMI(MBB, MBBI, DL, TII->get(ARM::VSCCLRMS))
1682  .add(predOps(ARMCC::AL))
1683  .addReg(ARM::VPR, RegState::Define);
1684  }
1685 
1686  // Load FP registers from stack.
1687  BuildMI(MBB, MBBI, DL, TII->get(ARM::VLLDM))
1688  .addReg(ARM::SP)
1689  .add(predOps(ARMCC::AL));
1690 
1691  // Pop the stack space
1692  BuildMI(MBB, MBBI, DL, TII->get(ARM::tADDspi), ARM::SP)
1693  .addReg(ARM::SP)
1694  .addImm(CMSE_FP_SAVE_SIZE >> 2)
1695  .add(predOps(ARMCC::AL));
1696  } else {
1697  // Restore the floating point context.
1698  BuildMI(MBB, MBBI, MBBI->getDebugLoc(), TII->get(ARM::VLDR_FPCXTS_post),
1699  ARM::SP)
1700  .addReg(ARM::SP)
1701  .addImm(8)
1702  .add(predOps(ARMCC::AL));
1703 
1704  // Pop all the callee-saved registers (s16-s31).
1705  MachineInstrBuilder VPOP =
1706  BuildMI(MBB, MBBI, DL, TII->get(ARM::VLDMSIA_UPD), ARM::SP)
1707  .addReg(ARM::SP)
1708  .add(predOps(ARMCC::AL));
1709  for (int Reg = ARM::S16; Reg <= ARM::S31; ++Reg)
1710  VPOP.addReg(Reg, RegState::Define);
1711  }
1712 }
1713 
1714 /// Expand a CMP_SWAP pseudo-inst to an ldrex/strex loop as simply as
1715 /// possible. This only gets used at -O0 so we don't care about efficiency of
1716 /// the generated code.
1717 bool ARMExpandPseudo::ExpandCMP_SWAP(MachineBasicBlock &MBB,
1719  unsigned LdrexOp, unsigned StrexOp,
1720  unsigned UxtOp,
1721  MachineBasicBlock::iterator &NextMBBI) {
1722  bool IsThumb = STI->isThumb();
1723  MachineInstr &MI = *MBBI;
1724  DebugLoc DL = MI.getDebugLoc();
1725  const MachineOperand &Dest = MI.getOperand(0);
1726  Register TempReg = MI.getOperand(1).getReg();
1727  // Duplicating undef operands into 2 instructions does not guarantee the same
1728  // value on both; However undef should be replaced by xzr anyway.
1729  assert(!MI.getOperand(2).isUndef() && "cannot handle undef");
1730  Register AddrReg = MI.getOperand(2).getReg();
1731  Register DesiredReg = MI.getOperand(3).getReg();
1732  Register NewReg = MI.getOperand(4).getReg();
1733 
1734  if (IsThumb) {
1735  assert(STI->hasV8MBaselineOps() &&
1736  "CMP_SWAP not expected to be custom expanded for Thumb1");
1737  assert((UxtOp == 0 || UxtOp == ARM::tUXTB || UxtOp == ARM::tUXTH) &&
1738  "ARMv8-M.baseline does not have t2UXTB/t2UXTH");
1739  assert((UxtOp == 0 || ARM::tGPRRegClass.contains(DesiredReg)) &&
1740  "DesiredReg used for UXT op must be tGPR");
1741  }
1742 
1743  MachineFunction *MF = MBB.getParent();
1744  auto LoadCmpBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
1745  auto StoreBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
1746  auto DoneBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
1747 
1748  MF->insert(++MBB.getIterator(), LoadCmpBB);
1749  MF->insert(++LoadCmpBB->getIterator(), StoreBB);
1750  MF->insert(++StoreBB->getIterator(), DoneBB);
1751 
1752  if (UxtOp) {
1753  MachineInstrBuilder MIB =
1754  BuildMI(MBB, MBBI, DL, TII->get(UxtOp), DesiredReg)
1755  .addReg(DesiredReg, RegState::Kill);
1756  if (!IsThumb)
1757  MIB.addImm(0);
1758  MIB.add(predOps(ARMCC::AL));
1759  }
1760 
1761  // .Lloadcmp:
1762  // ldrex rDest, [rAddr]
1763  // cmp rDest, rDesired
1764  // bne .Ldone
1765 
1766  MachineInstrBuilder MIB;
1767  MIB = BuildMI(LoadCmpBB, DL, TII->get(LdrexOp), Dest.getReg());
1768  MIB.addReg(AddrReg);
1769  if (LdrexOp == ARM::t2LDREX)
1770  MIB.addImm(0); // a 32-bit Thumb ldrex (only) allows an offset.
1771  MIB.add(predOps(ARMCC::AL));
1772 
1773  unsigned CMPrr = IsThumb ? ARM::tCMPhir : ARM::CMPrr;
1774  BuildMI(LoadCmpBB, DL, TII->get(CMPrr))
1775  .addReg(Dest.getReg(), getKillRegState(Dest.isDead()))
1776  .addReg(DesiredReg)
1777  .add(predOps(ARMCC::AL));
1778  unsigned Bcc = IsThumb ? ARM::tBcc : ARM::Bcc;
1779  BuildMI(LoadCmpBB, DL, TII->get(Bcc))
1780  .addMBB(DoneBB)
1781  .addImm(ARMCC::NE)
1782  .addReg(ARM::CPSR, RegState::Kill);
1783  LoadCmpBB->addSuccessor(DoneBB);
1784  LoadCmpBB->addSuccessor(StoreBB);
1785 
1786  // .Lstore:
1787  // strex rTempReg, rNew, [rAddr]
1788  // cmp rTempReg, #0
1789  // bne .Lloadcmp
1790  MIB = BuildMI(StoreBB, DL, TII->get(StrexOp), TempReg)
1791  .addReg(NewReg)
1792  .addReg(AddrReg);
1793  if (StrexOp == ARM::t2STREX)
1794  MIB.addImm(0); // a 32-bit Thumb strex (only) allows an offset.
1795  MIB.add(predOps(ARMCC::AL));
1796 
1797  unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
1798  BuildMI(StoreBB, DL, TII->get(CMPri))
1799  .addReg(TempReg, RegState::Kill)
1800  .addImm(0)
1801  .add(predOps(ARMCC::AL));
1802  BuildMI(StoreBB, DL, TII->get(Bcc))
1803  .addMBB(LoadCmpBB)
1804  .addImm(ARMCC::NE)
1805  .addReg(ARM::CPSR, RegState::Kill);
1806  StoreBB->addSuccessor(LoadCmpBB);
1807  StoreBB->addSuccessor(DoneBB);
1808 
1809  DoneBB->splice(DoneBB->end(), &MBB, MI, MBB.end());
1810  DoneBB->transferSuccessors(&MBB);
1811 
1812  MBB.addSuccessor(LoadCmpBB);
1813 
1814  NextMBBI = MBB.end();
1815  MI.eraseFromParent();
1816 
1817  // Recompute livein lists.
1818  LivePhysRegs LiveRegs;
1819  computeAndAddLiveIns(LiveRegs, *DoneBB);
1820  computeAndAddLiveIns(LiveRegs, *StoreBB);
1821  computeAndAddLiveIns(LiveRegs, *LoadCmpBB);
1822  // Do an extra pass around the loop to get loop carried registers right.
1823  StoreBB->clearLiveIns();
1824  computeAndAddLiveIns(LiveRegs, *StoreBB);
1825  LoadCmpBB->clearLiveIns();
1826  computeAndAddLiveIns(LiveRegs, *LoadCmpBB);
1827 
1828  return true;
1829 }
1830 
1831 /// ARM's ldrexd/strexd take a consecutive register pair (represented as a
1832 /// single GPRPair register), Thumb's take two separate registers so we need to
1833 /// extract the subregs from the pair.
1835  unsigned Flags, bool IsThumb,
1836  const TargetRegisterInfo *TRI) {
1837  if (IsThumb) {
1838  Register RegLo = TRI->getSubReg(Reg.getReg(), ARM::gsub_0);
1839  Register RegHi = TRI->getSubReg(Reg.getReg(), ARM::gsub_1);
1840  MIB.addReg(RegLo, Flags);
1841  MIB.addReg(RegHi, Flags);
1842  } else
1843  MIB.addReg(Reg.getReg(), Flags);
1844 }
1845 
1846 /// Expand a 64-bit CMP_SWAP to an ldrexd/strexd loop.
1847 bool ARMExpandPseudo::ExpandCMP_SWAP_64(MachineBasicBlock &MBB,
1849  MachineBasicBlock::iterator &NextMBBI) {
1850  bool IsThumb = STI->isThumb();
1851  MachineInstr &MI = *MBBI;
1852  DebugLoc DL = MI.getDebugLoc();
1853  MachineOperand &Dest = MI.getOperand(0);
1854  Register TempReg = MI.getOperand(1).getReg();
1855  // Duplicating undef operands into 2 instructions does not guarantee the same
1856  // value on both; However undef should be replaced by xzr anyway.
1857  assert(!MI.getOperand(2).isUndef() && "cannot handle undef");
1858  Register AddrReg = MI.getOperand(2).getReg();
1859  Register DesiredReg = MI.getOperand(3).getReg();
1860  MachineOperand New = MI.getOperand(4);
1861  New.setIsKill(false);
1862 
1863  Register DestLo = TRI->getSubReg(Dest.getReg(), ARM::gsub_0);
1864  Register DestHi = TRI->getSubReg(Dest.getReg(), ARM::gsub_1);
1865  Register DesiredLo = TRI->getSubReg(DesiredReg, ARM::gsub_0);
1866  Register DesiredHi = TRI->getSubReg(DesiredReg, ARM::gsub_1);
1867 
1868  MachineFunction *MF = MBB.getParent();
1869  auto LoadCmpBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
1870  auto StoreBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
1871  auto DoneBB = MF->CreateMachineBasicBlock(MBB.getBasicBlock());
1872 
1873  MF->insert(++MBB.getIterator(), LoadCmpBB);
1874  MF->insert(++LoadCmpBB->getIterator(), StoreBB);
1875  MF->insert(++StoreBB->getIterator(), DoneBB);
1876 
1877  // .Lloadcmp:
1878  // ldrexd rDestLo, rDestHi, [rAddr]
1879  // cmp rDestLo, rDesiredLo
1880  // sbcs dead rTempReg, rDestHi, rDesiredHi
1881  // bne .Ldone
1882  unsigned LDREXD = IsThumb ? ARM::t2LDREXD : ARM::LDREXD;
1883  MachineInstrBuilder MIB;
1884  MIB = BuildMI(LoadCmpBB, DL, TII->get(LDREXD));
1885  addExclusiveRegPair(MIB, Dest, RegState::Define, IsThumb, TRI);
1886  MIB.addReg(AddrReg).add(predOps(ARMCC::AL));
1887 
1888  unsigned CMPrr = IsThumb ? ARM::tCMPhir : ARM::CMPrr;
1889  BuildMI(LoadCmpBB, DL, TII->get(CMPrr))
1890  .addReg(DestLo, getKillRegState(Dest.isDead()))
1891  .addReg(DesiredLo)
1892  .add(predOps(ARMCC::AL));
1893 
1894  BuildMI(LoadCmpBB, DL, TII->get(CMPrr))
1895  .addReg(DestHi, getKillRegState(Dest.isDead()))
1896  .addReg(DesiredHi)
1897  .addImm(ARMCC::EQ).addReg(ARM::CPSR, RegState::Kill);
1898 
1899  unsigned Bcc = IsThumb ? ARM::tBcc : ARM::Bcc;
1900  BuildMI(LoadCmpBB, DL, TII->get(Bcc))
1901  .addMBB(DoneBB)
1902  .addImm(ARMCC::NE)
1903  .addReg(ARM::CPSR, RegState::Kill);
1904  LoadCmpBB->addSuccessor(DoneBB);
1905  LoadCmpBB->addSuccessor(StoreBB);
1906 
1907  // .Lstore:
1908  // strexd rTempReg, rNewLo, rNewHi, [rAddr]
1909  // cmp rTempReg, #0
1910  // bne .Lloadcmp
1911  unsigned STREXD = IsThumb ? ARM::t2STREXD : ARM::STREXD;
1912  MIB = BuildMI(StoreBB, DL, TII->get(STREXD), TempReg);
1913  unsigned Flags = getKillRegState(New.isDead());
1914  addExclusiveRegPair(MIB, New, Flags, IsThumb, TRI);
1915  MIB.addReg(AddrReg).add(predOps(ARMCC::AL));
1916 
1917  unsigned CMPri = IsThumb ? ARM::t2CMPri : ARM::CMPri;
1918  BuildMI(StoreBB, DL, TII->get(CMPri))
1919  .addReg(TempReg, RegState::Kill)
1920  .addImm(0)
1921  .add(predOps(ARMCC::AL));
1922  BuildMI(StoreBB, DL, TII->get(Bcc))
1923  .addMBB(LoadCmpBB)
1924  .addImm(ARMCC::NE)
1925  .addReg(ARM::CPSR, RegState::Kill);
1926  StoreBB->addSuccessor(LoadCmpBB);
1927  StoreBB->addSuccessor(DoneBB);
1928 
1929  DoneBB->splice(DoneBB->end(), &MBB, MI, MBB.end());
1930  DoneBB->transferSuccessors(&MBB);
1931 
1932  MBB.addSuccessor(LoadCmpBB);
1933 
1934  NextMBBI = MBB.end();
1935  MI.eraseFromParent();
1936 
1937  // Recompute livein lists.
1938  LivePhysRegs LiveRegs;
1939  computeAndAddLiveIns(LiveRegs, *DoneBB);
1940  computeAndAddLiveIns(LiveRegs, *StoreBB);
1941  computeAndAddLiveIns(LiveRegs, *LoadCmpBB);
1942  // Do an extra pass around the loop to get loop carried registers right.
1943  StoreBB->clearLiveIns();
1944  computeAndAddLiveIns(LiveRegs, *StoreBB);
1945  LoadCmpBB->clearLiveIns();
1946  computeAndAddLiveIns(LiveRegs, *LoadCmpBB);
1947 
1948  return true;
1949 }
1950 
1953  MachineBasicBlock::iterator MBBI, int JumpReg,
1954  const LivePhysRegs &LiveRegs, bool Thumb1Only) {
1955  const DebugLoc &DL = MBBI->getDebugLoc();
1956  if (Thumb1Only) { // push Lo and Hi regs separately
1957  MachineInstrBuilder PushMIB =
1958  BuildMI(MBB, MBBI, DL, TII.get(ARM::tPUSH)).add(predOps(ARMCC::AL));
1959  for (int Reg = ARM::R4; Reg < ARM::R8; ++Reg) {
1960  PushMIB.addReg(
1961  Reg, Reg == JumpReg || LiveRegs.contains(Reg) ? 0 : RegState::Undef);
1962  }
1963 
1964  // Thumb1 can only tPUSH low regs, so we copy the high regs to the low
1965  // regs that we just saved and push the low regs again, taking care to
1966  // not clobber JumpReg. If JumpReg is one of the low registers, push first
1967  // the values of r9-r11, and then r8. That would leave them ordered in
1968  // memory, and allow us to later pop them with a single instructions.
1969  // FIXME: Could also use any of r0-r3 that are free (including in the
1970  // first PUSH above).
1971  for (int LoReg = ARM::R7, HiReg = ARM::R11; LoReg >= ARM::R4; --LoReg) {
1972  if (JumpReg == LoReg)
1973  continue;
1974  BuildMI(MBB, MBBI, DL, TII.get(ARM::tMOVr), LoReg)
1975  .addReg(HiReg, LiveRegs.contains(HiReg) ? 0 : RegState::Undef)
1976  .add(predOps(ARMCC::AL));
1977  --HiReg;
1978  }
1979  MachineInstrBuilder PushMIB2 =
1980  BuildMI(MBB, MBBI, DL, TII.get(ARM::tPUSH)).add(predOps(ARMCC::AL));
1981  for (int Reg = ARM::R4; Reg < ARM::R8; ++Reg) {
1982  if (Reg == JumpReg)
1983  continue;
1984  PushMIB2.addReg(Reg, RegState::Kill);
1985  }
1986 
1987  // If we couldn't use a low register for temporary storage (because it was
1988  // the JumpReg), use r4 or r5, whichever is not JumpReg. It has already been
1989  // saved.
1990  if (JumpReg >= ARM::R4 && JumpReg <= ARM::R7) {
1991  int LoReg = JumpReg == ARM::R4 ? ARM::R5 : ARM::R4;
1992  BuildMI(MBB, MBBI, DL, TII.get(ARM::tMOVr), LoReg)
1993  .addReg(ARM::R8, LiveRegs.contains(ARM::R8) ? 0 : RegState::Undef)
1994  .add(predOps(ARMCC::AL));
1995  BuildMI(MBB, MBBI, DL, TII.get(ARM::tPUSH))
1996  .add(predOps(ARMCC::AL))
1997  .addReg(LoReg, RegState::Kill);
1998  }
1999  } else { // push Lo and Hi registers with a single instruction
2000  MachineInstrBuilder PushMIB =
2001  BuildMI(MBB, MBBI, DL, TII.get(ARM::t2STMDB_UPD), ARM::SP)
2002  .addReg(ARM::SP)
2003  .add(predOps(ARMCC::AL));
2004  for (int Reg = ARM::R4; Reg < ARM::R12; ++Reg) {
2005  PushMIB.addReg(
2006  Reg, Reg == JumpReg || LiveRegs.contains(Reg) ? 0 : RegState::Undef);
2007  }
2008  }
2009 }
2010 
2013  MachineBasicBlock::iterator MBBI, int JumpReg,
2014  bool Thumb1Only) {
2015  const DebugLoc &DL = MBBI->getDebugLoc();
2016  if (Thumb1Only) {
2017  MachineInstrBuilder PopMIB =
2018  BuildMI(MBB, MBBI, DL, TII.get(ARM::tPOP)).add(predOps(ARMCC::AL));
2019  for (int R = 0; R < 4; ++R) {
2020  PopMIB.addReg(ARM::R4 + R, RegState::Define);
2021  BuildMI(MBB, MBBI, DL, TII.get(ARM::tMOVr), ARM::R8 + R)
2023  .add(predOps(ARMCC::AL));
2024  }
2025  MachineInstrBuilder PopMIB2 =
2026  BuildMI(MBB, MBBI, DL, TII.get(ARM::tPOP)).add(predOps(ARMCC::AL));
2027  for (int R = 0; R < 4; ++R)
2028  PopMIB2.addReg(ARM::R4 + R, RegState::Define);
2029  } else { // pop Lo and Hi registers with a single instruction
2030  MachineInstrBuilder PopMIB =
2031  BuildMI(MBB, MBBI, DL, TII.get(ARM::t2LDMIA_UPD), ARM::SP)
2032  .addReg(ARM::SP)
2033  .add(predOps(ARMCC::AL));
2034  for (int Reg = ARM::R4; Reg < ARM::R12; ++Reg)
2035  PopMIB.addReg(Reg, RegState::Define);
2036  }
2037 }
2038 
2039 bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
2041  MachineBasicBlock::iterator &NextMBBI) {
2042  MachineInstr &MI = *MBBI;
2043  unsigned Opcode = MI.getOpcode();
2044  switch (Opcode) {
2045  default:
2046  return false;
2047 
2048  case ARM::VBSPd:
2049  case ARM::VBSPq: {
2050  Register DstReg = MI.getOperand(0).getReg();
2051  if (DstReg == MI.getOperand(3).getReg()) {
2052  // Expand to VBIT
2053  unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBITd : ARM::VBITq;
2054  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
2055  .add(MI.getOperand(0))
2056  .add(MI.getOperand(3))
2057  .add(MI.getOperand(2))
2058  .add(MI.getOperand(1))
2059  .addImm(MI.getOperand(4).getImm())
2060  .add(MI.getOperand(5));
2061  } else if (DstReg == MI.getOperand(2).getReg()) {
2062  // Expand to VBIF
2063  unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBIFd : ARM::VBIFq;
2064  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
2065  .add(MI.getOperand(0))
2066  .add(MI.getOperand(2))
2067  .add(MI.getOperand(3))
2068  .add(MI.getOperand(1))
2069  .addImm(MI.getOperand(4).getImm())
2070  .add(MI.getOperand(5));
2071  } else {
2072  // Expand to VBSL
2073  unsigned NewOpc = Opcode == ARM::VBSPd ? ARM::VBSLd : ARM::VBSLq;
2074  if (DstReg == MI.getOperand(1).getReg()) {
2075  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
2076  .add(MI.getOperand(0))
2077  .add(MI.getOperand(1))
2078  .add(MI.getOperand(2))
2079  .add(MI.getOperand(3))
2080  .addImm(MI.getOperand(4).getImm())
2081  .add(MI.getOperand(5));
2082  } else {
2083  // Use move to satisfy constraints
2084  unsigned MoveOpc = Opcode == ARM::VBSPd ? ARM::VORRd : ARM::VORRq;
2085  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(MoveOpc))
2086  .addReg(DstReg,
2088  getRenamableRegState(MI.getOperand(0).isRenamable()))
2089  .add(MI.getOperand(1))
2090  .add(MI.getOperand(1))
2091  .addImm(MI.getOperand(4).getImm())
2092  .add(MI.getOperand(5));
2093  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc))
2094  .add(MI.getOperand(0))
2095  .addReg(DstReg,
2096  RegState::Kill |
2097  getRenamableRegState(MI.getOperand(0).isRenamable()))
2098  .add(MI.getOperand(2))
2099  .add(MI.getOperand(3))
2100  .addImm(MI.getOperand(4).getImm())
2101  .add(MI.getOperand(5));
2102  }
2103  }
2104  MI.eraseFromParent();
2105  return true;
2106  }
2107 
2108  case ARM::TCRETURNdi:
2109  case ARM::TCRETURNri: {
2111  assert(MBBI->isReturn() &&
2112  "Can only insert epilog into returning blocks");
2113  unsigned RetOpcode = MBBI->getOpcode();
2114  DebugLoc dl = MBBI->getDebugLoc();
2115  const ARMBaseInstrInfo &TII = *static_cast<const ARMBaseInstrInfo *>(
2117 
2118  // Tail call return: adjust the stack pointer and jump to callee.
2120  MachineOperand &JumpTarget = MBBI->getOperand(0);
2121 
2122  // Jump to label or value in register.
2123  if (RetOpcode == ARM::TCRETURNdi) {
2124  unsigned TCOpcode =
2125  STI->isThumb()
2126  ? (STI->isTargetMachO() ? ARM::tTAILJMPd : ARM::tTAILJMPdND)
2127  : ARM::TAILJMPd;
2128  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII.get(TCOpcode));
2129  if (JumpTarget.isGlobal())
2130  MIB.addGlobalAddress(JumpTarget.getGlobal(), JumpTarget.getOffset(),
2131  JumpTarget.getTargetFlags());
2132  else {
2133  assert(JumpTarget.isSymbol());
2134  MIB.addExternalSymbol(JumpTarget.getSymbolName(),
2135  JumpTarget.getTargetFlags());
2136  }
2137 
2138  // Add the default predicate in Thumb mode.
2139  if (STI->isThumb())
2140  MIB.add(predOps(ARMCC::AL));
2141  } else if (RetOpcode == ARM::TCRETURNri) {
2142  unsigned Opcode =
2143  STI->isThumb() ? ARM::tTAILJMPr
2144  : (STI->hasV4TOps() ? ARM::TAILJMPr : ARM::TAILJMPr4);
2145  BuildMI(MBB, MBBI, dl,
2146  TII.get(Opcode))
2147  .addReg(JumpTarget.getReg(), RegState::Kill);
2148  }
2149 
2150  auto NewMI = std::prev(MBBI);
2151  for (unsigned i = 2, e = MBBI->getNumOperands(); i != e; ++i)
2152  NewMI->addOperand(MBBI->getOperand(i));
2153 
2154 
2155  // Update call site info and delete the pseudo instruction TCRETURN.
2156  if (MI.isCandidateForCallSiteEntry())
2157  MI.getMF()->moveCallSiteInfo(&MI, &*NewMI);
2158  MBB.erase(MBBI);
2159 
2160  MBBI = NewMI;
2161  return true;
2162  }
2163  case ARM::tBXNS_RET: {
2164  MachineBasicBlock &AfterBB = CMSEClearFPRegs(MBB, MBBI);
2165 
2166  if (STI->hasV8_1MMainlineOps()) {
2167  // Restore the non-secure floating point context.
2168  BuildMI(MBB, MBBI, MBBI->getDebugLoc(),
2169  TII->get(ARM::VLDR_FPCXTNS_post), ARM::SP)
2170  .addReg(ARM::SP)
2171  .addImm(4)
2172  .add(predOps(ARMCC::AL));
2173  }
2174 
2175  // Clear all GPR that are not a use of the return instruction.
2176  assert(llvm::all_of(MBBI->operands(), [](const MachineOperand &Op) {
2177  return !Op.isReg() || Op.getReg() != ARM::R12;
2178  }));
2179  SmallVector<unsigned, 5> ClearRegs;
2181  *MBBI, {ARM::R0, ARM::R1, ARM::R2, ARM::R3, ARM::R12}, ClearRegs);
2182  CMSEClearGPRegs(AfterBB, AfterBB.end(), MBBI->getDebugLoc(), ClearRegs,
2183  ARM::LR);
2184 
2185  MachineInstrBuilder NewMI =
2186  BuildMI(AfterBB, AfterBB.end(), MBBI->getDebugLoc(),
2187  TII->get(ARM::tBXNS))
2188  .addReg(ARM::LR)
2189  .add(predOps(ARMCC::AL));
2190  for (const MachineOperand &Op : MI.operands())
2191  NewMI->addOperand(Op);
2192  MI.eraseFromParent();
2193  return true;
2194  }
2195  case ARM::tBLXNS_CALL: {
2196  DebugLoc DL = MBBI->getDebugLoc();
2197  unsigned JumpReg = MBBI->getOperand(0).getReg();
2198 
2199  // Figure out which registers are live at the point immediately before the
2200  // call. When we indiscriminately push a set of registers, the live
2201  // registers are added as ordinary use operands, whereas dead registers
2202  // are "undef".
2203  LivePhysRegs LiveRegs(*TRI);
2204  LiveRegs.addLiveOuts(MBB);
2205  for (const MachineInstr &MI : make_range(MBB.rbegin(), MBBI.getReverse()))
2206  LiveRegs.stepBackward(MI);
2207  LiveRegs.stepBackward(*MBBI);
2208 
2209  CMSEPushCalleeSaves(*TII, MBB, MBBI, JumpReg, LiveRegs,
2210  AFI->isThumb1OnlyFunction());
2211 
2212  SmallVector<unsigned, 16> ClearRegs;
2214  {ARM::R0, ARM::R1, ARM::R2, ARM::R3, ARM::R4,
2215  ARM::R5, ARM::R6, ARM::R7, ARM::R8, ARM::R9,
2216  ARM::R10, ARM::R11, ARM::R12},
2217  ClearRegs);
2218  auto OriginalClearRegs = ClearRegs;
2219 
2220  // Get the first cleared register as a scratch (to use later with tBIC).
2221  // We need to use the first so we can ensure it is a low register.
2222  unsigned ScratchReg = ClearRegs.front();
2223 
2224  // Clear LSB of JumpReg
2225  if (AFI->isThumb2Function()) {
2226  BuildMI(MBB, MBBI, DL, TII->get(ARM::t2BICri), JumpReg)
2227  .addReg(JumpReg)
2228  .addImm(1)
2229  .add(predOps(ARMCC::AL))
2230  .add(condCodeOp());
2231  } else {
2232  // We need to use an extra register to cope with 8M Baseline,
2233  // since we have saved all of the registers we are ok to trash a non
2234  // argument register here.
2235  BuildMI(MBB, MBBI, DL, TII->get(ARM::tMOVi8), ScratchReg)
2236  .add(condCodeOp())
2237  .addImm(1)
2238  .add(predOps(ARMCC::AL));
2239  BuildMI(MBB, MBBI, DL, TII->get(ARM::tBIC), JumpReg)
2240  .addReg(ARM::CPSR, RegState::Define)
2241  .addReg(JumpReg)
2242  .addReg(ScratchReg)
2243  .add(predOps(ARMCC::AL));
2244  }
2245 
2246  CMSESaveClearFPRegs(MBB, MBBI, DL, LiveRegs,
2247  ClearRegs); // save+clear FP regs with ClearRegs
2248  CMSEClearGPRegs(MBB, MBBI, DL, ClearRegs, JumpReg);
2249 
2250  const MachineInstrBuilder NewCall =
2251  BuildMI(MBB, MBBI, DL, TII->get(ARM::tBLXNSr))
2252  .add(predOps(ARMCC::AL))
2253  .addReg(JumpReg, RegState::Kill);
2254 
2255  for (int I = 1, E = MI.getNumOperands(); I != E; ++I)
2256  NewCall->addOperand(MI.getOperand(I));
2257  if (MI.isCandidateForCallSiteEntry())
2258  MI.getMF()->moveCallSiteInfo(&MI, NewCall.getInstr());
2259 
2260  CMSERestoreFPRegs(MBB, MBBI, DL, OriginalClearRegs); // restore FP registers
2261 
2262  CMSEPopCalleeSaves(*TII, MBB, MBBI, JumpReg, AFI->isThumb1OnlyFunction());
2263 
2264  MI.eraseFromParent();
2265  return true;
2266  }
2267  case ARM::VMOVHcc:
2268  case ARM::VMOVScc:
2269  case ARM::VMOVDcc: {
2270  unsigned newOpc = Opcode != ARM::VMOVDcc ? ARM::VMOVS : ARM::VMOVD;
2271  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(newOpc),
2272  MI.getOperand(1).getReg())
2273  .add(MI.getOperand(2))
2274  .addImm(MI.getOperand(3).getImm()) // 'pred'
2275  .add(MI.getOperand(4))
2276  .add(makeImplicit(MI.getOperand(1)));
2277 
2278  MI.eraseFromParent();
2279  return true;
2280  }
2281  case ARM::t2MOVCCr:
2282  case ARM::MOVCCr: {
2283  unsigned Opc = AFI->isThumbFunction() ? ARM::t2MOVr : ARM::MOVr;
2284  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc),
2285  MI.getOperand(1).getReg())
2286  .add(MI.getOperand(2))
2287  .addImm(MI.getOperand(3).getImm()) // 'pred'
2288  .add(MI.getOperand(4))
2289  .add(condCodeOp()) // 's' bit
2290  .add(makeImplicit(MI.getOperand(1)));
2291 
2292  MI.eraseFromParent();
2293  return true;
2294  }
2295  case ARM::MOVCCsi: {
2296  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
2297  (MI.getOperand(1).getReg()))
2298  .add(MI.getOperand(2))
2299  .addImm(MI.getOperand(3).getImm())
2300  .addImm(MI.getOperand(4).getImm()) // 'pred'
2301  .add(MI.getOperand(5))
2302  .add(condCodeOp()) // 's' bit
2303  .add(makeImplicit(MI.getOperand(1)));
2304 
2305  MI.eraseFromParent();
2306  return true;
2307  }
2308  case ARM::MOVCCsr: {
2309  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsr),
2310  (MI.getOperand(1).getReg()))
2311  .add(MI.getOperand(2))
2312  .add(MI.getOperand(3))
2313  .addImm(MI.getOperand(4).getImm())
2314  .addImm(MI.getOperand(5).getImm()) // 'pred'
2315  .add(MI.getOperand(6))
2316  .add(condCodeOp()) // 's' bit
2317  .add(makeImplicit(MI.getOperand(1)));
2318 
2319  MI.eraseFromParent();
2320  return true;
2321  }
2322  case ARM::t2MOVCCi16:
2323  case ARM::MOVCCi16: {
2324  unsigned NewOpc = AFI->isThumbFunction() ? ARM::t2MOVi16 : ARM::MOVi16;
2325  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc),
2326  MI.getOperand(1).getReg())
2327  .addImm(MI.getOperand(2).getImm())
2328  .addImm(MI.getOperand(3).getImm()) // 'pred'
2329  .add(MI.getOperand(4))
2330  .add(makeImplicit(MI.getOperand(1)));
2331  MI.eraseFromParent();
2332  return true;
2333  }
2334  case ARM::t2MOVCCi:
2335  case ARM::MOVCCi: {
2336  unsigned Opc = AFI->isThumbFunction() ? ARM::t2MOVi : ARM::MOVi;
2337  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc),
2338  MI.getOperand(1).getReg())
2339  .addImm(MI.getOperand(2).getImm())
2340  .addImm(MI.getOperand(3).getImm()) // 'pred'
2341  .add(MI.getOperand(4))
2342  .add(condCodeOp()) // 's' bit
2343  .add(makeImplicit(MI.getOperand(1)));
2344 
2345  MI.eraseFromParent();
2346  return true;
2347  }
2348  case ARM::t2MVNCCi:
2349  case ARM::MVNCCi: {
2350  unsigned Opc = AFI->isThumbFunction() ? ARM::t2MVNi : ARM::MVNi;
2351  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc),
2352  MI.getOperand(1).getReg())
2353  .addImm(MI.getOperand(2).getImm())
2354  .addImm(MI.getOperand(3).getImm()) // 'pred'
2355  .add(MI.getOperand(4))
2356  .add(condCodeOp()) // 's' bit
2357  .add(makeImplicit(MI.getOperand(1)));
2358 
2359  MI.eraseFromParent();
2360  return true;
2361  }
2362  case ARM::t2MOVCClsl:
2363  case ARM::t2MOVCClsr:
2364  case ARM::t2MOVCCasr:
2365  case ARM::t2MOVCCror: {
2366  unsigned NewOpc;
2367  switch (Opcode) {
2368  case ARM::t2MOVCClsl: NewOpc = ARM::t2LSLri; break;
2369  case ARM::t2MOVCClsr: NewOpc = ARM::t2LSRri; break;
2370  case ARM::t2MOVCCasr: NewOpc = ARM::t2ASRri; break;
2371  case ARM::t2MOVCCror: NewOpc = ARM::t2RORri; break;
2372  default: llvm_unreachable("unexpeced conditional move");
2373  }
2374  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc),
2375  MI.getOperand(1).getReg())
2376  .add(MI.getOperand(2))
2377  .addImm(MI.getOperand(3).getImm())
2378  .addImm(MI.getOperand(4).getImm()) // 'pred'
2379  .add(MI.getOperand(5))
2380  .add(condCodeOp()) // 's' bit
2381  .add(makeImplicit(MI.getOperand(1)));
2382  MI.eraseFromParent();
2383  return true;
2384  }
2385  case ARM::Int_eh_sjlj_dispatchsetup: {
2386  MachineFunction &MF = *MI.getParent()->getParent();
2387  const ARMBaseInstrInfo *AII =
2388  static_cast<const ARMBaseInstrInfo*>(TII);
2389  const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
2390  // For functions using a base pointer, we rematerialize it (via the frame
2391  // pointer) here since eh.sjlj.setjmp and eh.sjlj.longjmp don't do it
2392  // for us. Otherwise, expand to nothing.
2393  if (RI.hasBasePointer(MF)) {
2394  int32_t NumBytes = AFI->getFramePtrSpillOffset();
2396  assert(MF.getSubtarget().getFrameLowering()->hasFP(MF) &&
2397  "base pointer without frame pointer?");
2398 
2399  if (AFI->isThumb2Function()) {
2400  emitT2RegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
2401  FramePtr, -NumBytes, ARMCC::AL, 0, *TII);
2402  } else if (AFI->isThumbFunction()) {
2403  emitThumbRegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
2404  FramePtr, -NumBytes, *TII, RI);
2405  } else {
2406  emitARMRegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
2407  FramePtr, -NumBytes, ARMCC::AL, 0,
2408  *TII);
2409  }
2410  // If there's dynamic realignment, adjust for it.
2411  if (RI.hasStackRealignment(MF)) {
2412  MachineFrameInfo &MFI = MF.getFrameInfo();
2413  Align MaxAlign = MFI.getMaxAlign();
2414  assert (!AFI->isThumb1OnlyFunction());
2415  // Emit bic r6, r6, MaxAlign
2416  assert(MaxAlign <= Align(256) &&
2417  "The BIC instruction cannot encode "
2418  "immediates larger than 256 with all lower "
2419  "bits set.");
2420  unsigned bicOpc = AFI->isThumbFunction() ?
2421  ARM::t2BICri : ARM::BICri;
2422  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(bicOpc), ARM::R6)
2424  .addImm(MaxAlign.value() - 1)
2425  .add(predOps(ARMCC::AL))
2426  .add(condCodeOp());
2427  }
2428  }
2429  MI.eraseFromParent();
2430  return true;
2431  }
2432 
2433  case ARM::MOVsrl_flag:
2434  case ARM::MOVsra_flag: {
2435  // These are just fancy MOVs instructions.
2436  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
2437  MI.getOperand(0).getReg())
2438  .add(MI.getOperand(1))
2440  (Opcode == ARM::MOVsrl_flag ? ARM_AM::lsr : ARM_AM::asr), 1))
2441  .add(predOps(ARMCC::AL))
2442  .addReg(ARM::CPSR, RegState::Define);
2443  MI.eraseFromParent();
2444  return true;
2445  }
2446  case ARM::RRX: {
2447  // This encodes as "MOVs Rd, Rm, rrx
2448  MachineInstrBuilder MIB =
2449  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
2450  MI.getOperand(0).getReg())
2451  .add(MI.getOperand(1))
2453  .add(predOps(ARMCC::AL))
2454  .add(condCodeOp());
2455  TransferImpOps(MI, MIB, MIB);
2456  MI.eraseFromParent();
2457  return true;
2458  }
2459  case ARM::tTPsoft:
2460  case ARM::TPsoft: {
2461  const bool Thumb = Opcode == ARM::tTPsoft;
2462 
2463  MachineInstrBuilder MIB;
2464  MachineFunction *MF = MBB.getParent();
2465  if (STI->genLongCalls()) {
2466  MachineConstantPool *MCP = MF->getConstantPool();
2467  unsigned PCLabelID = AFI->createPICLabelUId();
2470  "__aeabi_read_tp", PCLabelID, 0);
2471  Register Reg = MI.getOperand(0).getReg();
2472  MIB =
2473  BuildMI(MBB, MBBI, MI.getDebugLoc(),
2474  TII->get(Thumb ? ARM::tLDRpci : ARM::LDRi12), Reg)
2476  if (!Thumb)
2477  MIB.addImm(0);
2478  MIB.add(predOps(ARMCC::AL));
2479 
2480  MIB =
2481  BuildMI(MBB, MBBI, MI.getDebugLoc(),
2482  TII->get(Thumb ? gettBLXrOpcode(*MF) : getBLXOpcode(*MF)));
2483  if (Thumb)
2484  MIB.add(predOps(ARMCC::AL));
2485  MIB.addReg(Reg, RegState::Kill);
2486  } else {
2487  MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
2488  TII->get(Thumb ? ARM::tBL : ARM::BL));
2489  if (Thumb)
2490  MIB.add(predOps(ARMCC::AL));
2491  MIB.addExternalSymbol("__aeabi_read_tp", 0);
2492  }
2493 
2494  MIB.cloneMemRefs(MI);
2495  TransferImpOps(MI, MIB, MIB);
2496  // Update the call site info.
2497  if (MI.isCandidateForCallSiteEntry())
2498  MF->moveCallSiteInfo(&MI, &*MIB);
2499  MI.eraseFromParent();
2500  return true;
2501  }
2502  case ARM::tLDRpci_pic:
2503  case ARM::t2LDRpci_pic: {
2504  unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
2505  ? ARM::tLDRpci : ARM::t2LDRpci;
2506  Register DstReg = MI.getOperand(0).getReg();
2507  bool DstIsDead = MI.getOperand(0).isDead();
2508  MachineInstrBuilder MIB1 =
2509  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewLdOpc), DstReg)
2510  .add(MI.getOperand(1))
2511  .add(predOps(ARMCC::AL));
2512  MIB1.cloneMemRefs(MI);
2513  MachineInstrBuilder MIB2 =
2514  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tPICADD))
2515  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2516  .addReg(DstReg)
2517  .add(MI.getOperand(2));
2518  TransferImpOps(MI, MIB1, MIB2);
2519  MI.eraseFromParent();
2520  return true;
2521  }
2522 
2523  case ARM::LDRLIT_ga_abs:
2524  case ARM::LDRLIT_ga_pcrel:
2525  case ARM::LDRLIT_ga_pcrel_ldr:
2526  case ARM::tLDRLIT_ga_abs:
2527  case ARM::tLDRLIT_ga_pcrel: {
2528  Register DstReg = MI.getOperand(0).getReg();
2529  bool DstIsDead = MI.getOperand(0).isDead();
2530  const MachineOperand &MO1 = MI.getOperand(1);
2531  auto Flags = MO1.getTargetFlags();
2532  const GlobalValue *GV = MO1.getGlobal();
2533  bool IsARM =
2534  Opcode != ARM::tLDRLIT_ga_pcrel && Opcode != ARM::tLDRLIT_ga_abs;
2535  bool IsPIC =
2536  Opcode != ARM::LDRLIT_ga_abs && Opcode != ARM::tLDRLIT_ga_abs;
2537  unsigned LDRLITOpc = IsARM ? ARM::LDRi12 : ARM::tLDRpci;
2538  unsigned PICAddOpc =
2539  IsARM
2540  ? (Opcode == ARM::LDRLIT_ga_pcrel_ldr ? ARM::PICLDR : ARM::PICADD)
2541  : ARM::tPICADD;
2542 
2543  // We need a new const-pool entry to load from.
2545  unsigned ARMPCLabelIndex = 0;
2547 
2548  if (IsPIC) {
2549  unsigned PCAdj = IsARM ? 8 : 4;
2550  auto Modifier = (Flags & ARMII::MO_GOT)
2551  ? ARMCP::GOT_PREL
2553  ARMPCLabelIndex = AFI->createPICLabelUId();
2555  GV, ARMPCLabelIndex, ARMCP::CPValue, PCAdj, Modifier,
2556  /*AddCurrentAddr*/ Modifier == ARMCP::GOT_PREL);
2557  } else
2559 
2560  MachineInstrBuilder MIB =
2561  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LDRLITOpc), DstReg)
2562  .addConstantPoolIndex(MCP->getConstantPoolIndex(CPV, Align(4)));
2563  if (IsARM)
2564  MIB.addImm(0);
2565  MIB.add(predOps(ARMCC::AL));
2566 
2567  if (IsPIC) {
2568  MachineInstrBuilder MIB =
2569  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(PICAddOpc))
2570  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2571  .addReg(DstReg)
2572  .addImm(ARMPCLabelIndex);
2573 
2574  if (IsARM)
2575  MIB.add(predOps(ARMCC::AL));
2576  }
2577 
2578  MI.eraseFromParent();
2579  return true;
2580  }
2581  case ARM::MOV_ga_pcrel:
2582  case ARM::MOV_ga_pcrel_ldr:
2583  case ARM::t2MOV_ga_pcrel: {
2584  // Expand into movw + movw. Also "add pc" / ldr [pc] in PIC mode.
2585  unsigned LabelId = AFI->createPICLabelUId();
2586  Register DstReg = MI.getOperand(0).getReg();
2587  bool DstIsDead = MI.getOperand(0).isDead();
2588  const MachineOperand &MO1 = MI.getOperand(1);
2589  const GlobalValue *GV = MO1.getGlobal();
2590  unsigned TF = MO1.getTargetFlags();
2591  bool isARM = Opcode != ARM::t2MOV_ga_pcrel;
2592  unsigned LO16Opc = isARM ? ARM::MOVi16_ga_pcrel : ARM::t2MOVi16_ga_pcrel;
2593  unsigned HI16Opc = isARM ? ARM::MOVTi16_ga_pcrel :ARM::t2MOVTi16_ga_pcrel;
2594  unsigned LO16TF = TF | ARMII::MO_LO16;
2595  unsigned HI16TF = TF | ARMII::MO_HI16;
2596  unsigned PICAddOpc = isARM
2597  ? (Opcode == ARM::MOV_ga_pcrel_ldr ? ARM::PICLDR : ARM::PICADD)
2598  : ARM::tPICADD;
2599  MachineInstrBuilder MIB1 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
2600  TII->get(LO16Opc), DstReg)
2601  .addGlobalAddress(GV, MO1.getOffset(), TF | LO16TF)
2602  .addImm(LabelId);
2603 
2604  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc), DstReg)
2605  .addReg(DstReg)
2606  .addGlobalAddress(GV, MO1.getOffset(), TF | HI16TF)
2607  .addImm(LabelId);
2608 
2609  MachineInstrBuilder MIB3 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
2610  TII->get(PICAddOpc))
2611  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
2612  .addReg(DstReg).addImm(LabelId);
2613  if (isARM) {
2614  MIB3.add(predOps(ARMCC::AL));
2615  if (Opcode == ARM::MOV_ga_pcrel_ldr)
2616  MIB3.cloneMemRefs(MI);
2617  }
2618  TransferImpOps(MI, MIB1, MIB3);
2619  MI.eraseFromParent();
2620  return true;
2621  }
2622 
2623  case ARM::MOVi32imm:
2624  case ARM::MOVCCi32imm:
2625  case ARM::t2MOVi32imm:
2626  case ARM::t2MOVCCi32imm:
2627  ExpandMOV32BitImm(MBB, MBBI);
2628  return true;
2629 
2630  case ARM::SUBS_PC_LR: {
2631  MachineInstrBuilder MIB =
2632  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri), ARM::PC)
2633  .addReg(ARM::LR)
2634  .add(MI.getOperand(0))
2635  .add(MI.getOperand(1))
2636  .add(MI.getOperand(2))
2637  .addReg(ARM::CPSR, RegState::Undef);
2638  TransferImpOps(MI, MIB, MIB);
2639  MI.eraseFromParent();
2640  return true;
2641  }
2642  case ARM::VLDMQIA: {
2643  unsigned NewOpc = ARM::VLDMDIA;
2644  MachineInstrBuilder MIB =
2645  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
2646  unsigned OpIdx = 0;
2647 
2648  // Grab the Q register destination.
2649  bool DstIsDead = MI.getOperand(OpIdx).isDead();
2650  Register DstReg = MI.getOperand(OpIdx++).getReg();
2651 
2652  // Copy the source register.
2653  MIB.add(MI.getOperand(OpIdx++));
2654 
2655  // Copy the predicate operands.
2656  MIB.add(MI.getOperand(OpIdx++));
2657  MIB.add(MI.getOperand(OpIdx++));
2658 
2659  // Add the destination operands (D subregs).
2660  Register D0 = TRI->getSubReg(DstReg, ARM::dsub_0);
2661  Register D1 = TRI->getSubReg(DstReg, ARM::dsub_1);
2662  MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead))
2663  .addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
2664 
2665  // Add an implicit def for the super-register.
2666  MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
2667  TransferImpOps(MI, MIB, MIB);
2668  MIB.cloneMemRefs(MI);
2669  MI.eraseFromParent();
2670  return true;
2671  }
2672 
2673  case ARM::VSTMQIA: {
2674  unsigned NewOpc = ARM::VSTMDIA;
2675  MachineInstrBuilder MIB =
2676  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
2677  unsigned OpIdx = 0;
2678 
2679  // Grab the Q register source.
2680  bool SrcIsKill = MI.getOperand(OpIdx).isKill();
2681  Register SrcReg = MI.getOperand(OpIdx++).getReg();
2682 
2683  // Copy the destination register.
2684  MachineOperand Dst(MI.getOperand(OpIdx++));
2685  MIB.add(Dst);
2686 
2687  // Copy the predicate operands.
2688  MIB.add(MI.getOperand(OpIdx++));
2689  MIB.add(MI.getOperand(OpIdx++));
2690 
2691  // Add the source operands (D subregs).
2692  Register D0 = TRI->getSubReg(SrcReg, ARM::dsub_0);
2693  Register D1 = TRI->getSubReg(SrcReg, ARM::dsub_1);
2694  MIB.addReg(D0, SrcIsKill ? RegState::Kill : 0)
2695  .addReg(D1, SrcIsKill ? RegState::Kill : 0);
2696 
2697  if (SrcIsKill) // Add an implicit kill for the Q register.
2698  MIB->addRegisterKilled(SrcReg, TRI, true);
2699 
2700  TransferImpOps(MI, MIB, MIB);
2701  MIB.cloneMemRefs(MI);
2702  MI.eraseFromParent();
2703  return true;
2704  }
2705 
2706  case ARM::VLD2q8Pseudo:
2707  case ARM::VLD2q16Pseudo:
2708  case ARM::VLD2q32Pseudo:
2709  case ARM::VLD2q8PseudoWB_fixed:
2710  case ARM::VLD2q16PseudoWB_fixed:
2711  case ARM::VLD2q32PseudoWB_fixed:
2712  case ARM::VLD2q8PseudoWB_register:
2713  case ARM::VLD2q16PseudoWB_register:
2714  case ARM::VLD2q32PseudoWB_register:
2715  case ARM::VLD3d8Pseudo:
2716  case ARM::VLD3d16Pseudo:
2717  case ARM::VLD3d32Pseudo:
2718  case ARM::VLD1d8TPseudo:
2719  case ARM::VLD1d8TPseudoWB_fixed:
2720  case ARM::VLD1d8TPseudoWB_register:
2721  case ARM::VLD1d16TPseudo:
2722  case ARM::VLD1d16TPseudoWB_fixed:
2723  case ARM::VLD1d16TPseudoWB_register:
2724  case ARM::VLD1d32TPseudo:
2725  case ARM::VLD1d32TPseudoWB_fixed:
2726  case ARM::VLD1d32TPseudoWB_register:
2727  case ARM::VLD1d64TPseudo:
2728  case ARM::VLD1d64TPseudoWB_fixed:
2729  case ARM::VLD1d64TPseudoWB_register:
2730  case ARM::VLD3d8Pseudo_UPD:
2731  case ARM::VLD3d16Pseudo_UPD:
2732  case ARM::VLD3d32Pseudo_UPD:
2733  case ARM::VLD3q8Pseudo_UPD:
2734  case ARM::VLD3q16Pseudo_UPD:
2735  case ARM::VLD3q32Pseudo_UPD:
2736  case ARM::VLD3q8oddPseudo:
2737  case ARM::VLD3q16oddPseudo:
2738  case ARM::VLD3q32oddPseudo:
2739  case ARM::VLD3q8oddPseudo_UPD:
2740  case ARM::VLD3q16oddPseudo_UPD:
2741  case ARM::VLD3q32oddPseudo_UPD:
2742  case ARM::VLD4d8Pseudo:
2743  case ARM::VLD4d16Pseudo:
2744  case ARM::VLD4d32Pseudo:
2745  case ARM::VLD1d8QPseudo:
2746  case ARM::VLD1d8QPseudoWB_fixed:
2747  case ARM::VLD1d8QPseudoWB_register:
2748  case ARM::VLD1d16QPseudo:
2749  case ARM::VLD1d16QPseudoWB_fixed:
2750  case ARM::VLD1d16QPseudoWB_register:
2751  case ARM::VLD1d32QPseudo:
2752  case ARM::VLD1d32QPseudoWB_fixed:
2753  case ARM::VLD1d32QPseudoWB_register:
2754  case ARM::VLD1d64QPseudo:
2755  case ARM::VLD1d64QPseudoWB_fixed:
2756  case ARM::VLD1d64QPseudoWB_register:
2757  case ARM::VLD1q8HighQPseudo:
2758  case ARM::VLD1q8HighQPseudo_UPD:
2759  case ARM::VLD1q8LowQPseudo_UPD:
2760  case ARM::VLD1q8HighTPseudo:
2761  case ARM::VLD1q8HighTPseudo_UPD:
2762  case ARM::VLD1q8LowTPseudo_UPD:
2763  case ARM::VLD1q16HighQPseudo:
2764  case ARM::VLD1q16HighQPseudo_UPD:
2765  case ARM::VLD1q16LowQPseudo_UPD:
2766  case ARM::VLD1q16HighTPseudo:
2767  case ARM::VLD1q16HighTPseudo_UPD:
2768  case ARM::VLD1q16LowTPseudo_UPD:
2769  case ARM::VLD1q32HighQPseudo:
2770  case ARM::VLD1q32HighQPseudo_UPD:
2771  case ARM::VLD1q32LowQPseudo_UPD:
2772  case ARM::VLD1q32HighTPseudo:
2773  case ARM::VLD1q32HighTPseudo_UPD:
2774  case ARM::VLD1q32LowTPseudo_UPD:
2775  case ARM::VLD1q64HighQPseudo:
2776  case ARM::VLD1q64HighQPseudo_UPD:
2777  case ARM::VLD1q64LowQPseudo_UPD:
2778  case ARM::VLD1q64HighTPseudo:
2779  case ARM::VLD1q64HighTPseudo_UPD:
2780  case ARM::VLD1q64LowTPseudo_UPD:
2781  case ARM::VLD4d8Pseudo_UPD:
2782  case ARM::VLD4d16Pseudo_UPD:
2783  case ARM::VLD4d32Pseudo_UPD:
2784  case ARM::VLD4q8Pseudo_UPD:
2785  case ARM::VLD4q16Pseudo_UPD:
2786  case ARM::VLD4q32Pseudo_UPD:
2787  case ARM::VLD4q8oddPseudo:
2788  case ARM::VLD4q16oddPseudo:
2789  case ARM::VLD4q32oddPseudo:
2790  case ARM::VLD4q8oddPseudo_UPD:
2791  case ARM::VLD4q16oddPseudo_UPD:
2792  case ARM::VLD4q32oddPseudo_UPD:
2793  case ARM::VLD3DUPd8Pseudo:
2794  case ARM::VLD3DUPd16Pseudo:
2795  case ARM::VLD3DUPd32Pseudo:
2796  case ARM::VLD3DUPd8Pseudo_UPD:
2797  case ARM::VLD3DUPd16Pseudo_UPD:
2798  case ARM::VLD3DUPd32Pseudo_UPD:
2799  case ARM::VLD4DUPd8Pseudo:
2800  case ARM::VLD4DUPd16Pseudo:
2801  case ARM::VLD4DUPd32Pseudo:
2802  case ARM::VLD4DUPd8Pseudo_UPD:
2803  case ARM::VLD4DUPd16Pseudo_UPD:
2804  case ARM::VLD4DUPd32Pseudo_UPD:
2805  case ARM::VLD2DUPq8EvenPseudo:
2806  case ARM::VLD2DUPq8OddPseudo:
2807  case ARM::VLD2DUPq16EvenPseudo:
2808  case ARM::VLD2DUPq16OddPseudo:
2809  case ARM::VLD2DUPq32EvenPseudo:
2810  case ARM::VLD2DUPq32OddPseudo:
2811  case ARM::VLD2DUPq8OddPseudoWB_fixed:
2812  case ARM::VLD2DUPq8OddPseudoWB_register:
2813  case ARM::VLD2DUPq16OddPseudoWB_fixed:
2814  case ARM::VLD2DUPq16OddPseudoWB_register:
2815  case ARM::VLD2DUPq32OddPseudoWB_fixed:
2816  case ARM::VLD2DUPq32OddPseudoWB_register:
2817  case ARM::VLD3DUPq8EvenPseudo:
2818  case ARM::VLD3DUPq8OddPseudo:
2819  case ARM::VLD3DUPq16EvenPseudo:
2820  case ARM::VLD3DUPq16OddPseudo:
2821  case ARM::VLD3DUPq32EvenPseudo:
2822  case ARM::VLD3DUPq32OddPseudo:
2823  case ARM::VLD3DUPq8OddPseudo_UPD:
2824  case ARM::VLD3DUPq16OddPseudo_UPD:
2825  case ARM::VLD3DUPq32OddPseudo_UPD:
2826  case ARM::VLD4DUPq8EvenPseudo:
2827  case ARM::VLD4DUPq8OddPseudo:
2828  case ARM::VLD4DUPq16EvenPseudo:
2829  case ARM::VLD4DUPq16OddPseudo:
2830  case ARM::VLD4DUPq32EvenPseudo:
2831  case ARM::VLD4DUPq32OddPseudo:
2832  case ARM::VLD4DUPq8OddPseudo_UPD:
2833  case ARM::VLD4DUPq16OddPseudo_UPD:
2834  case ARM::VLD4DUPq32OddPseudo_UPD:
2835  ExpandVLD(MBBI);
2836  return true;
2837 
2838  case ARM::VST2q8Pseudo:
2839  case ARM::VST2q16Pseudo:
2840  case ARM::VST2q32Pseudo:
2841  case ARM::VST2q8PseudoWB_fixed:
2842  case ARM::VST2q16PseudoWB_fixed:
2843  case ARM::VST2q32PseudoWB_fixed:
2844  case ARM::VST2q8PseudoWB_register:
2845  case ARM::VST2q16PseudoWB_register:
2846  case ARM::VST2q32PseudoWB_register:
2847  case ARM::VST3d8Pseudo:
2848  case ARM::VST3d16Pseudo:
2849  case ARM::VST3d32Pseudo:
2850  case ARM::VST1d8TPseudo:
2851  case ARM::VST1d8TPseudoWB_fixed:
2852  case ARM::VST1d8TPseudoWB_register:
2853  case ARM::VST1d16TPseudo:
2854  case ARM::VST1d16TPseudoWB_fixed:
2855  case ARM::VST1d16TPseudoWB_register:
2856  case ARM::VST1d32TPseudo:
2857  case ARM::VST1d32TPseudoWB_fixed:
2858  case ARM::VST1d32TPseudoWB_register:
2859  case ARM::VST1d64TPseudo:
2860  case ARM::VST1d64TPseudoWB_fixed:
2861  case ARM::VST1d64TPseudoWB_register:
2862  case ARM::VST3d8Pseudo_UPD:
2863  case ARM::VST3d16Pseudo_UPD:
2864  case ARM::VST3d32Pseudo_UPD:
2865  case ARM::VST3q8Pseudo_UPD:
2866  case ARM::VST3q16Pseudo_UPD:
2867  case ARM::VST3q32Pseudo_UPD:
2868  case ARM::VST3q8oddPseudo:
2869  case ARM::VST3q16oddPseudo:
2870  case ARM::VST3q32oddPseudo:
2871  case ARM::VST3q8oddPseudo_UPD:
2872  case ARM::VST3q16oddPseudo_UPD:
2873  case ARM::VST3q32oddPseudo_UPD:
2874  case ARM::VST4d8Pseudo:
2875  case ARM::VST4d16Pseudo:
2876  case ARM::VST4d32Pseudo:
2877  case ARM::VST1d8QPseudo:
2878  case ARM::VST1d8QPseudoWB_fixed:
2879  case ARM::VST1d8QPseudoWB_register:
2880  case ARM::VST1d16QPseudo:
2881  case ARM::VST1d16QPseudoWB_fixed:
2882  case ARM::VST1d16QPseudoWB_register:
2883  case ARM::VST1d32QPseudo:
2884  case ARM::VST1d32QPseudoWB_fixed:
2885  case ARM::VST1d32QPseudoWB_register:
2886  case ARM::VST1d64QPseudo:
2887  case ARM::VST1d64QPseudoWB_fixed:
2888  case ARM::VST1d64QPseudoWB_register:
2889  case ARM::VST4d8Pseudo_UPD:
2890  case ARM::VST4d16Pseudo_UPD:
2891  case ARM::VST4d32Pseudo_UPD:
2892  case ARM::VST1q8HighQPseudo:
2893  case ARM::VST1q8LowQPseudo_UPD:
2894  case ARM::VST1q8HighTPseudo:
2895  case ARM::VST1q8LowTPseudo_UPD:
2896  case ARM::VST1q16HighQPseudo:
2897  case ARM::VST1q16LowQPseudo_UPD:
2898  case ARM::VST1q16HighTPseudo:
2899  case ARM::VST1q16LowTPseudo_UPD:
2900  case ARM::VST1q32HighQPseudo:
2901  case ARM::VST1q32LowQPseudo_UPD:
2902  case ARM::VST1q32HighTPseudo:
2903  case ARM::VST1q32LowTPseudo_UPD:
2904  case ARM::VST1q64HighQPseudo:
2905  case ARM::VST1q64LowQPseudo_UPD:
2906  case ARM::VST1q64HighTPseudo:
2907  case ARM::VST1q64LowTPseudo_UPD:
2908  case ARM::VST1q8HighTPseudo_UPD:
2909  case ARM::VST1q16HighTPseudo_UPD:
2910  case ARM::VST1q32HighTPseudo_UPD:
2911  case ARM::VST1q64HighTPseudo_UPD:
2912  case ARM::VST1q8HighQPseudo_UPD:
2913  case ARM::VST1q16HighQPseudo_UPD:
2914  case ARM::VST1q32HighQPseudo_UPD:
2915  case ARM::VST1q64HighQPseudo_UPD:
2916  case ARM::VST4q8Pseudo_UPD:
2917  case ARM::VST4q16Pseudo_UPD:
2918  case ARM::VST4q32Pseudo_UPD:
2919  case ARM::VST4q8oddPseudo:
2920  case ARM::VST4q16oddPseudo:
2921  case ARM::VST4q32oddPseudo:
2922  case ARM::VST4q8oddPseudo_UPD:
2923  case ARM::VST4q16oddPseudo_UPD:
2924  case ARM::VST4q32oddPseudo_UPD:
2925  ExpandVST(MBBI);
2926  return true;
2927 
2928  case ARM::VLD1LNq8Pseudo:
2929  case ARM::VLD1LNq16Pseudo:
2930  case ARM::VLD1LNq32Pseudo:
2931  case ARM::VLD1LNq8Pseudo_UPD:
2932  case ARM::VLD1LNq16Pseudo_UPD:
2933  case ARM::VLD1LNq32Pseudo_UPD:
2934  case ARM::VLD2LNd8Pseudo:
2935  case ARM::VLD2LNd16Pseudo:
2936  case ARM::VLD2LNd32Pseudo:
2937  case ARM::VLD2LNq16Pseudo:
2938  case ARM::VLD2LNq32Pseudo:
2939  case ARM::VLD2LNd8Pseudo_UPD:
2940  case ARM::VLD2LNd16Pseudo_UPD:
2941  case ARM::VLD2LNd32Pseudo_UPD:
2942  case ARM::VLD2LNq16Pseudo_UPD:
2943  case ARM::VLD2LNq32Pseudo_UPD:
2944  case ARM::VLD3LNd8Pseudo:
2945  case ARM::VLD3LNd16Pseudo:
2946  case ARM::VLD3LNd32Pseudo:
2947  case ARM::VLD3LNq16Pseudo:
2948  case ARM::VLD3LNq32Pseudo:
2949  case ARM::VLD3LNd8Pseudo_UPD:
2950  case ARM::VLD3LNd16Pseudo_UPD:
2951  case ARM::VLD3LNd32Pseudo_UPD:
2952  case ARM::VLD3LNq16Pseudo_UPD:
2953  case ARM::VLD3LNq32Pseudo_UPD:
2954  case ARM::VLD4LNd8Pseudo:
2955  case ARM::VLD4LNd16Pseudo:
2956  case ARM::VLD4LNd32Pseudo:
2957  case ARM::VLD4LNq16Pseudo:
2958  case ARM::VLD4LNq32Pseudo:
2959  case ARM::VLD4LNd8Pseudo_UPD:
2960  case ARM::VLD4LNd16Pseudo_UPD:
2961  case ARM::VLD4LNd32Pseudo_UPD:
2962  case ARM::VLD4LNq16Pseudo_UPD:
2963  case ARM::VLD4LNq32Pseudo_UPD:
2964  case ARM::VST1LNq8Pseudo:
2965  case ARM::VST1LNq16Pseudo:
2966  case ARM::VST1LNq32Pseudo:
2967  case ARM::VST1LNq8Pseudo_UPD:
2968  case ARM::VST1LNq16Pseudo_UPD:
2969  case ARM::VST1LNq32Pseudo_UPD:
2970  case ARM::VST2LNd8Pseudo:
2971  case ARM::VST2LNd16Pseudo:
2972  case ARM::VST2LNd32Pseudo:
2973  case ARM::VST2LNq16Pseudo:
2974  case ARM::VST2LNq32Pseudo:
2975  case ARM::VST2LNd8Pseudo_UPD:
2976  case ARM::VST2LNd16Pseudo_UPD:
2977  case ARM::VST2LNd32Pseudo_UPD:
2978  case ARM::VST2LNq16Pseudo_UPD:
2979  case ARM::VST2LNq32Pseudo_UPD:
2980  case ARM::VST3LNd8Pseudo:
2981  case ARM::VST3LNd16Pseudo:
2982  case ARM::VST3LNd32Pseudo:
2983  case ARM::VST3LNq16Pseudo:
2984  case ARM::VST3LNq32Pseudo:
2985  case ARM::VST3LNd8Pseudo_UPD:
2986  case ARM::VST3LNd16Pseudo_UPD:
2987  case ARM::VST3LNd32Pseudo_UPD:
2988  case ARM::VST3LNq16Pseudo_UPD:
2989  case ARM::VST3LNq32Pseudo_UPD:
2990  case ARM::VST4LNd8Pseudo:
2991  case ARM::VST4LNd16Pseudo:
2992  case ARM::VST4LNd32Pseudo:
2993  case ARM::VST4LNq16Pseudo:
2994  case ARM::VST4LNq32Pseudo:
2995  case ARM::VST4LNd8Pseudo_UPD:
2996  case ARM::VST4LNd16Pseudo_UPD:
2997  case ARM::VST4LNd32Pseudo_UPD:
2998  case ARM::VST4LNq16Pseudo_UPD:
2999  case ARM::VST4LNq32Pseudo_UPD:
3000  ExpandLaneOp(MBBI);
3001  return true;
3002 
3003  case ARM::VTBL3Pseudo: ExpandVTBL(MBBI, ARM::VTBL3, false); return true;
3004  case ARM::VTBL4Pseudo: ExpandVTBL(MBBI, ARM::VTBL4, false); return true;
3005  case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true); return true;
3006  case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true); return true;
3007 
3008  case ARM::MQQPRLoad:
3009  case ARM::MQQPRStore:
3010  case ARM::MQQQQPRLoad:
3011  case ARM::MQQQQPRStore:
3012  ExpandMQQPRLoadStore(MBBI);
3013  return true;
3014 
3015  case ARM::tCMP_SWAP_8:
3016  assert(STI->isThumb());
3017  return ExpandCMP_SWAP(MBB, MBBI, ARM::t2LDREXB, ARM::t2STREXB, ARM::tUXTB,
3018  NextMBBI);
3019  case ARM::tCMP_SWAP_16:
3020  assert(STI->isThumb());
3021  return ExpandCMP_SWAP(MBB, MBBI, ARM::t2LDREXH, ARM::t2STREXH, ARM::tUXTH,
3022  NextMBBI);
3023 
3024  case ARM::CMP_SWAP_8:
3025  assert(!STI->isThumb());
3026  return ExpandCMP_SWAP(MBB, MBBI, ARM::LDREXB, ARM::STREXB, ARM::UXTB,
3027  NextMBBI);
3028  case ARM::CMP_SWAP_16:
3029  assert(!STI->isThumb());
3030  return ExpandCMP_SWAP(MBB, MBBI, ARM::LDREXH, ARM::STREXH, ARM::UXTH,
3031  NextMBBI);
3032  case ARM::CMP_SWAP_32:
3033  if (STI->isThumb())
3034  return ExpandCMP_SWAP(MBB, MBBI, ARM::t2LDREX, ARM::t2STREX, 0,
3035  NextMBBI);
3036  else
3037  return ExpandCMP_SWAP(MBB, MBBI, ARM::LDREX, ARM::STREX, 0, NextMBBI);
3038 
3039  case ARM::CMP_SWAP_64:
3040  return ExpandCMP_SWAP_64(MBB, MBBI, NextMBBI);
3041 
3042  case ARM::tBL_PUSHLR:
3043  case ARM::BL_PUSHLR: {
3044  const bool Thumb = Opcode == ARM::tBL_PUSHLR;
3045  Register Reg = MI.getOperand(0).getReg();
3046  assert(Reg == ARM::LR && "expect LR register!");
3047  MachineInstrBuilder MIB;
3048  if (Thumb) {
3049  // push {lr}
3050  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tPUSH))
3051  .add(predOps(ARMCC::AL))
3052  .addReg(Reg);
3053 
3054  // bl __gnu_mcount_nc
3055  MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::tBL));
3056  } else {
3057  // stmdb sp!, {lr}
3058  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::STMDB_UPD))
3059  .addReg(ARM::SP, RegState::Define)
3060  .addReg(ARM::SP)
3061  .add(predOps(ARMCC::AL))
3062  .addReg(Reg);
3063 
3064  // bl __gnu_mcount_nc
3065  MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::BL));
3066  }
3067  MIB.cloneMemRefs(MI);
3068  for (unsigned i = 1; i < MI.getNumOperands(); ++i) MIB.add(MI.getOperand(i));
3069  MI.eraseFromParent();
3070  return true;
3071  }
3072  case ARM::LOADDUAL:
3073  case ARM::STOREDUAL: {
3074  Register PairReg = MI.getOperand(0).getReg();
3075 
3076  MachineInstrBuilder MIB =
3077  BuildMI(MBB, MBBI, MI.getDebugLoc(),
3078  TII->get(Opcode == ARM::LOADDUAL ? ARM::LDRD : ARM::STRD))
3079  .addReg(TRI->getSubReg(PairReg, ARM::gsub_0),
3080  Opcode == ARM::LOADDUAL ? RegState::Define : 0)
3081  .addReg(TRI->getSubReg(PairReg, ARM::gsub_1),
3082  Opcode == ARM::LOADDUAL ? RegState::Define : 0);
3083  for (unsigned i = 1; i < MI.getNumOperands(); i++)
3084  MIB.add(MI.getOperand(i));
3085  MIB.add(predOps(ARMCC::AL));
3086  MIB.cloneMemRefs(MI);
3087  MI.eraseFromParent();
3088  return true;
3089  }
3090  }
3091 }
3092 
3093 bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
3094  bool Modified = false;
3095 
3097  while (MBBI != E) {
3098  MachineBasicBlock::iterator NMBBI = std::next(MBBI);
3099  Modified |= ExpandMI(MBB, MBBI, NMBBI);
3100  MBBI = NMBBI;
3101  }
3102 
3103  return Modified;
3104 }
3105 
3106 bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
3107  STI = &static_cast<const ARMSubtarget &>(MF.getSubtarget());
3108  TII = STI->getInstrInfo();
3109  TRI = STI->getRegisterInfo();
3110  AFI = MF.getInfo<ARMFunctionInfo>();
3111 
3112  LLVM_DEBUG(dbgs() << "********** ARM EXPAND PSEUDO INSTRUCTIONS **********\n"
3113  << "********** Function: " << MF.getName() << '\n');
3114 
3115  bool Modified = false;
3116  for (MachineBasicBlock &MBB : MF)
3117  Modified |= ExpandMBB(MBB);
3118  if (VerifyARMPseudo)
3119  MF.verify(this, "After expanding ARM pseudo instructions.");
3120 
3121  LLVM_DEBUG(dbgs() << "***************************************************\n");
3122  return Modified;
3123 }
3124 
3125 /// createARMExpandPseudoPass - returns an instance of the pseudo instruction
3126 /// expansion pass.
3128  return new ARMExpandPseudo();
3129 }
i
i
Definition: README.txt:29
ARMSubtarget.h
llvm::MachineOperand::MO_BlockAddress
@ MO_BlockAddress
Address of a basic block.
Definition: MachineOperand.h:63
llvm::ARMISD::RRX
@ RRX
Definition: ARMISelLowering.h:105
llvm::ARMFunctionInfo
ARMFunctionInfo - This class is derived from MachineFunctionInfo and contains private ARM-specific in...
Definition: ARMMachineFunctionInfo.h:27
MI
IRTranslator LLVM IR MI
Definition: IRTranslator.cpp:105
llvm::MachineOperand::MO_Immediate
@ MO_Immediate
Immediate operand.
Definition: MachineOperand.h:53
llvm::MachineInstrBuilder::addImm
const MachineInstrBuilder & addImm(int64_t Val) const
Add a new immediate operand.
Definition: MachineInstrBuilder.h:131
llvm::MachineConstantPool::getConstantPoolIndex
unsigned getConstantPoolIndex(const Constant *C, Align Alignment)
getConstantPoolIndex - Create a new entry in the constant pool or return an existing one.
Definition: MachineFunction.cpp:1457
llvm
This file implements support for optimizing divisions by a constant.
Definition: AllocatorList.h:23
makeImplicit
static MachineOperand makeImplicit(const MachineOperand &MO)
Definition: ARMExpandPseudoInsts.cpp:965
llvm::ARMII::MO_HI16
@ MO_HI16
MO_HI16 - On a symbol operand, this represents a relocation containing higher 16 bit of the address.
Definition: ARMBaseInfo.h:250
Reg
unsigned Reg
Definition: MachineSink.cpp:1566
llvm::ARM_AM::lsr
@ lsr
Definition: ARMAddressingModes.h:31
UseMI
MachineInstrBuilder & UseMI
Definition: AArch64ExpandPseudoInsts.cpp:102
llvm::make_range
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
Definition: iterator_range.h:53
IsAnAddressOperand
static bool IsAnAddressOperand(const MachineOperand &MO)
Definition: ARMExpandPseudoInsts.cpp:928
llvm::MachineBasicBlock::getBasicBlock
const BasicBlock * getBasicBlock() const
Return the LLVM basic block that this instance corresponded to originally.
Definition: MachineBasicBlock.h:202
llvm::ARMSubtarget
Definition: ARMSubtarget.h:46
llvm::MachineOperand::MO_ShuffleMask
@ MO_ShuffleMask
Other IR Constant for ISel (shuffle masks)
Definition: MachineOperand.h:71
llvm::MachineOperand::getGlobal
const GlobalValue * getGlobal() const
Definition: MachineOperand.h:563
addExclusiveRegPair
static void addExclusiveRegPair(MachineInstrBuilder &MIB, MachineOperand &Reg, unsigned Flags, bool IsThumb, const TargetRegisterInfo *TRI)
ARM's ldrexd/strexd take a consecutive register pair (represented as a single GPRPair register),...
Definition: ARMExpandPseudoInsts.cpp:1834
llvm::MachineOperand::MO_RegisterLiveOut
@ MO_RegisterLiveOut
Mask of live-out registers.
Definition: MachineOperand.h:65
llvm::MachineInstrBuilder::add
const MachineInstrBuilder & add(const MachineOperand &MO) const
Definition: MachineInstrBuilder.h:224
llvm::lower_bound
auto lower_bound(R &&Range, T &&Value)
Provide wrappers to std::lower_bound which take ranges instead of having to pass begin/end explicitly...
Definition: STLExtras.h:1661
llvm::TargetSubtargetInfo::getInstrInfo
virtual const TargetInstrInfo * getInstrInfo() const
Definition: TargetSubtargetInfo.h:92
llvm::emitT2RegPlusImmediate
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)
Definition: Thumb2InstrInfo.cpp:275
NEONLdStTable
static const NEONLdStTableEntry NEONLdStTable[]
Definition: ARMExpandPseudoInsts.cpp:185
llvm::RegState::Implicit
@ Implicit
Not emitted register (e.g. carry, or temporary result).
Definition: MachineInstrBuilder.h:46
contains
return AArch64::GPR64RegClass contains(Reg)
llvm::SmallVector< unsigned, 4 >
llvm::ARM_AM::getSOImmTwoPartSecond
unsigned getSOImmTwoPartSecond(unsigned V)
getSOImmTwoPartSecond - If V is a value that satisfies isSOImmTwoPartVal, return the second chunk of ...
Definition: ARMAddressingModes.h:199
DEBUG_TYPE
#define DEBUG_TYPE
Definition: ARMExpandPseudoInsts.cpp:30
ARMMachineFunctionInfo.h
llvm::MachineFunctionPass
MachineFunctionPass - This class adapts the FunctionPass interface to allow convenient creation of pa...
Definition: MachineFunctionPass.h:30
llvm::LivePhysRegs
A set of physical registers with utility functions to track liveness when walking backward/forward th...
Definition: LivePhysRegs.h:48
llvm::cl::Hidden
@ Hidden
Definition: CommandLine.h:143
llvm::ARMISD::LDRD
@ LDRD
Definition: ARMISelLowering.h:358
R4
#define R4(n)
llvm::TargetRegisterInfo
TargetRegisterInfo base class - We assume that the target defines a static array of TargetRegisterDes...
Definition: TargetRegisterInfo.h:233
llvm::MachineFunction::moveCallSiteInfo
void moveCallSiteInfo(const MachineInstr *Old, const MachineInstr *New)
Move the call site info from Old to \New call site info.
Definition: MachineFunction.cpp:949
llvm::MachineConstantPoolValue
Abstract base class for all machine specific constantpool value subclasses.
Definition: MachineConstantPool.h:35
llvm::MachineOperand::isSymbol
bool isSymbol() const
isSymbol - Tests if this is a MO_ExternalSymbol operand.
Definition: MachineOperand.h:341
llvm::Function::getContext
LLVMContext & getContext() const
getContext - Return a reference to the LLVMContext associated with this function.
Definition: Function.cpp:321
llvm::sys::path::end
const_iterator end(StringRef path)
Get end iterator over path.
Definition: Path.cpp:233
llvm::MachineOperand::MO_CFIIndex
@ MO_CFIIndex
MCCFIInstruction index.
Definition: MachineOperand.h:68
llvm::MachineFunction::insert
void insert(iterator MBBI, MachineBasicBlock *MBB)
Definition: MachineFunction.h:831
llvm::LivePhysRegs::contains
bool contains(MCPhysReg Reg) const
Returns true if register Reg is contained in the set.
Definition: LivePhysRegs.h:106
llvm::getDeadRegState
unsigned getDeadRegState(bool B)
Definition: MachineInstrBuilder.h:511
llvm::ARMCP::no_modifier
@ no_modifier
Definition: ARMConstantPoolValue.h:47
llvm::MachineFunctionProperties
Properties which a MachineFunction may have at a given point in time.
Definition: MachineFunction.h:111
CMSE_FP_SAVE_SIZE
static const int CMSE_FP_SAVE_SIZE
Definition: ARMExpandPseudoInsts.cpp:1089
llvm::dump
void dump(const SparseBitVector< ElementSize > &LHS, raw_ostream &out)
Definition: SparseBitVector.h:876
llvm::SmallVectorImpl::pop_back_val
LLVM_NODISCARD T pop_back_val()
Definition: SmallVector.h:635
llvm::ARM::PredBlockMask::TE
@ TE
LLVM_ATTRIBUTE_UNUSED
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:188
llvm::MachineOperand::getOffset
int64_t getOffset() const
Return the offset from the symbol in this operand.
Definition: MachineOperand.h:600
TRI
unsigned const TargetRegisterInfo * TRI
Definition: MachineSink.cpp:1567
llvm::ARCISD::BL
@ BL
Definition: ARCISelLowering.h:34
LLVM_DEBUG
#define LLVM_DEBUG(X)
Definition: Debug.h:101
llvm::MachineOperand::MO_Register
@ MO_Register
Register operand.
Definition: MachineOperand.h:52
llvm::getUndefRegState
unsigned getUndefRegState(bool B)
Definition: MachineInstrBuilder.h:514
llvm::RegState::Kill
@ Kill
The last use of a register.
Definition: MachineInstrBuilder.h:48
llvm::ISD::INLINEASM
@ INLINEASM
INLINEASM - Represents an inline asm block.
Definition: ISDOpcodes.h:980
llvm::MachineBasicBlock::erase
instr_iterator erase(instr_iterator I)
Remove an instruction from the instruction list and delete it.
Definition: MachineBasicBlock.cpp:1304
llvm::getBLXOpcode
unsigned getBLXOpcode(const MachineFunction &MF)
Definition: ARMBaseInstrInfo.cpp:6549
llvm::dbgs
raw_ostream & dbgs()
dbgs() - This returns a reference to a raw_ostream for debugging messages.
Definition: Debug.cpp:163
llvm::RegState::Define
@ Define
Register definition.
Definition: MachineInstrBuilder.h:44
llvm::codeview::CPUType::Thumb
@ Thumb
llvm::MachineBasicBlock::addSuccessor
void addSuccessor(MachineBasicBlock *Succ, BranchProbability Prob=BranchProbability::getUnknown())
Add Succ as a successor of this MachineBasicBlock.
Definition: MachineBasicBlock.cpp:751
llvm::MachineOperand::isKill
bool isKill() const
Definition: MachineOperand.h:390
llvm::ARM_AM::getSOImmTwoPartFirst
unsigned getSOImmTwoPartFirst(unsigned V)
getSOImmTwoPartFirst - If V is a value that satisfies isSOImmTwoPartVal, return the first chunk of it...
Definition: ARMAddressingModes.h:193
ARMConstantPoolValue.h
llvm::finalizeBundle
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...
Definition: MachineInstrBundle.cpp:123
llvm::getDefRegState
unsigned getDefRegState(bool B)
Definition: MachineInstrBuilder.h:502
R2
#define R2(n)
llvm::all_of
bool all_of(R &&range, UnaryPredicate P)
Provide wrappers to std::all_of which take ranges instead of having to pass begin/end explicitly.
Definition: STLExtras.h:1551
llvm::codeview::EncodedFramePtrReg::FramePtr
@ FramePtr
llvm::ARMCC::EQ
@ EQ
Definition: ARMBaseInfo.h:31
llvm::TargetInstrInfo
TargetInstrInfo - Interface to description of machine instruction set.
Definition: TargetInstrInfo.h:97
VerifyARMPseudo
static cl::opt< bool > VerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden, cl::desc("Verify machine code after expanding ARM pseudos"))
llvm::getRenamableRegState
unsigned getRenamableRegState(bool B)
Definition: MachineInstrBuilder.h:523
llvm::MachineInstrBuilder::addMBB
const MachineInstrBuilder & addMBB(MachineBasicBlock *MBB, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:146
llvm::RegState::Undef
@ Undef
Value of the register doesn't matter.
Definition: MachineInstrBuilder.h:52
llvm::MachineOperand::MO_GlobalAddress
@ MO_GlobalAddress
Address of a global value.
Definition: MachineOperand.h:62
E
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
llvm::ARMISD::VMOVSR
@ VMOVSR
Definition: ARMISelLowering.h:115
llvm::MachineOperand::getImm
int64_t getImm() const
Definition: MachineOperand.h:537
llvm::MachineFunction::getInfo
Ty * getInfo()
getInfo - Keep track of various per-function pieces of information for backends that would like to do...
Definition: MachineFunction.h:728
llvm::MachineOperand::isUse
bool isUse() const
Definition: MachineOperand.h:370
llvm::ARMBaseRegisterInfo::getFrameRegister
Register getFrameRegister(const MachineFunction &MF) const override
Definition: ARMBaseRegisterInfo.cpp:479
GetDSubRegs
static void GetDSubRegs(unsigned Reg, NEONRegSpacing RegSpc, const TargetRegisterInfo *TRI, unsigned &D0, unsigned &D1, unsigned &D2, unsigned &D3)
GetDSubRegs - Get 4 D subregisters of a Q, QQ, or QQQQ register, corresponding to the specified regis...
Definition: ARMExpandPseudoInsts.cpp:533
llvm::BitVector::count
size_type count() const
count - Returns the number of bits which are set.
Definition: BitVector.h:154
llvm::BitVector::size
size_type size() const
size - Returns the number of bits in this bitvector.
Definition: BitVector.h:151
llvm::MachineOperand::MO_FrameIndex
@ MO_FrameIndex
Abstract Stack Frame Index.
Definition: MachineOperand.h:57
llvm::Register::isPhysicalRegister
static bool isPhysicalRegister(unsigned Reg)
Return true if the specified register number is in the physical register namespace.
Definition: Register.h:65
llvm::LivePhysRegs::addLiveOuts
void addLiveOuts(const MachineBasicBlock &MBB)
Adds all live-out registers of basic block MBB.
Definition: LivePhysRegs.cpp:230
llvm::MachineInstr::addRegisterKilled
bool addRegisterKilled(Register IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
We have determined MI kills a register.
Definition: MachineInstr.cpp:1881
TII
const HexagonInstrInfo * TII
Definition: HexagonCopyToCombine.cpp:129
llvm::MCInstrDesc
Describe properties that are true of each instruction in the target description file.
Definition: MCInstrDesc.h:195
llvm::MachineOperand
MachineOperand class - Representation of each machine instruction operand.
Definition: MachineOperand.h:49
llvm::MachineFunctionProperties::set
MachineFunctionProperties & set(Property P)
Definition: MachineFunction.h:173
llvm::ARMConstantPoolSymbol::Create
static ARMConstantPoolSymbol * Create(LLVMContext &C, StringRef s, unsigned ID, unsigned char PCAdj)
Definition: ARMConstantPoolValue.cpp:233
CMSEPushCalleeSaves
static void CMSEPushCalleeSaves(const TargetInstrInfo &TII, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, int JumpReg, const LivePhysRegs &LiveRegs, bool Thumb1Only)
Definition: ARMExpandPseudoInsts.cpp:1951
llvm::ARMISD::VMOVDRR
@ VMOVDRR
Definition: ARMISelLowering.h:114
llvm::TargetFrameLowering::hasFP
virtual bool hasFP(const MachineFunction &MF) const =0
hasFP - Return true if the specified function should have a dedicated frame pointer register.
determineFPRegsToClear
static bool determineFPRegsToClear(const MachineInstr &MI, BitVector &ClearRegs)
Definition: ARMExpandPseudoInsts.cpp:1141
LoopDeletionResult::Modified
@ Modified
llvm::computeAndAddLiveIns
void computeAndAddLiveIns(LivePhysRegs &LiveRegs, MachineBasicBlock &MBB)
Convenience function combining computeLiveIns() and addLiveIns().
Definition: LivePhysRegs.cpp:339
llvm::BitVector
Definition: BitVector.h:74
Align
uint64_t Align
Definition: ELFObjHandler.cpp:83
llvm::Align
This struct is a compact representation of a valid (non-zero power of two) alignment.
Definition: Alignment.h:39
definesOrUsesFPReg
static bool definesOrUsesFPReg(const MachineInstr &MI)
Definition: ARMExpandPseudoInsts.cpp:1663
llvm::MachineInstrBuilder::addExternalSymbol
const MachineInstrBuilder & addExternalSymbol(const char *FnName, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:184
CMSEPopCalleeSaves
static void CMSEPopCalleeSaves(const TargetInstrInfo &TII, MachineBasicBlock &MBB, MachineBasicBlock::iterator MBBI, int JumpReg, bool Thumb1Only)
Definition: ARMExpandPseudoInsts.cpp:2011
llvm::MachineBasicBlock
Definition: MachineBasicBlock.h:95
llvm::MachineInstrBuilder::cloneMemRefs
const MachineInstrBuilder & cloneMemRefs(const MachineInstr &OtherMI) const
Definition: MachineInstrBuilder.h:213
llvm::MachineFunctionProperties::Property::NoVRegs
@ NoVRegs
llvm::ARM_AM::rrx
@ rrx
Definition: ARMAddressingModes.h:33
llvm::ARMCC::NE
@ NE
Definition: ARMBaseInfo.h:32
llvm::ARMCC::AL
@ AL
Definition: ARMBaseInfo.h:45
llvm::MachineFunction::getSubtarget
const TargetSubtargetInfo & getSubtarget() const
getSubtarget - Return the subtarget for which this machine code is being compiled.
Definition: MachineFunction.h:630
llvm::cl::opt< bool >
llvm::MachineOperand::MO_Metadata
@ MO_Metadata
Metadata reference (for debug info)
Definition: MachineOperand.h:66
llvm::GlobalValue
Definition: GlobalValue.h:44
llvm::LivePhysRegs::stepBackward
void stepBackward(const MachineInstr &MI)
Simulates liveness when stepping backwards over an instruction(bundle).
Definition: LivePhysRegs.cpp:68
llvm::MachineOperand::isUndef
bool isUndef() const
Definition: MachineOperand.h:395
ARMBaseRegisterInfo.h
llvm::RegState::ImplicitDefine
@ ImplicitDefine
Definition: MachineInstrBuilder.h:63
llvm::MachineOperand::getTargetFlags
unsigned getTargetFlags() const
Definition: MachineOperand.h:221
llvm::MachineOperand::isReg
bool isReg() const
isReg - Tests if this is a MO_Register operand.
Definition: MachineOperand.h:321
llvm::MachineInstr
Representation of each machine instruction.
Definition: MachineInstr.h:64
llvm::MachineInstrBuilder
Definition: MachineInstrBuilder.h:69
llvm::ARMCP::GOT_PREL
@ GOT_PREL
Thread Local Storage (General Dynamic Mode)
Definition: ARMConstantPoolValue.h:49
llvm::getInstrPredicate
ARMCC::CondCodes getInstrPredicate(const MachineInstr &MI, Register &PredReg)
getInstrPredicate - If instruction is predicated, returns its predicate condition,...
Definition: ARMBaseInstrInfo.cpp:2250
D
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
llvm::numbers::e
constexpr double e
Definition: MathExtras.h:57
llvm::TargetRegisterInfo::getMatchingSuperReg
MCRegister getMatchingSuperReg(MCRegister Reg, unsigned SubIdx, const TargetRegisterClass *RC) const
Return a super-register of the specified register Reg so its sub-register of index SubIdx is Reg.
Definition: TargetRegisterInfo.h:577
llvm::MachineConstantPool
The MachineConstantPool class keeps track of constants referenced by a function which must be spilled...
Definition: MachineConstantPool.h:117
llvm::operator<
bool operator<(int64_t V1, const APSInt &V2)
Definition: APSInt.h:338
llvm::MachineOperand::isDead
bool isDead() const
Definition: MachineOperand.h:385
llvm::condCodeOp
static MachineOperand condCodeOp(unsigned CCReg=0)
Get the operand corresponding to the conditional code result.
Definition: ARMBaseInstrInfo.h:548
llvm::MachineOperand::MO_Predicate
@ MO_Predicate
Generic predicate for ISel.
Definition: MachineOperand.h:70
I
#define I(x, y, z)
Definition: MD5.cpp:59
llvm::createARMExpandPseudoPass
FunctionPass * createARMExpandPseudoPass()
createARMExpandPseudoPass - returns an instance of the pseudo instruction expansion pass.
Definition: ARMExpandPseudoInsts.cpp:3127
llvm::ARMBaseInstrInfo
Definition: ARMBaseInstrInfo.h:37
llvm::MachineOperand::MO_MCSymbol
@ MO_MCSymbol
MCSymbol reference (for debug/eh info)
Definition: MachineOperand.h:67
llvm::ARMISD::VMOVRRD
@ VMOVRRD
Definition: ARMISelLowering.h:113
llvm::MachineFunction::CreateMachineBasicBlock
MachineBasicBlock * CreateMachineBasicBlock(const BasicBlock *bb=nullptr)
CreateMachineBasicBlock - Allocate a new MachineBasicBlock.
Definition: MachineFunction.cpp:415
llvm::MachineOperand::getType
MachineOperandType getType() const
getType - Returns the MachineOperandType for this operand.
Definition: MachineOperand.h:219
llvm::MachineBasicBlock::getLastNonDebugInstr
iterator getLastNonDebugInstr(bool SkipPseudoOp=true)
Returns an iterator to the last non-debug instruction in the basic block, or end().
Definition: MachineBasicBlock.cpp:267
MachineFunctionPass.h
llvm::ARMISD::STRD
@ STRD
Definition: ARMISelLowering.h:359
INITIALIZE_PASS
INITIALIZE_PASS(ARMExpandPseudo, DEBUG_TYPE, ARM_EXPAND_PSEUDO_NAME, false, false) void ARMExpandPseudo
TransferImpOps - Transfer implicit operands on the pseudo instruction to the instructions created fro...
Definition: ARMExpandPseudoInsts.cpp:119
llvm::MachineFunction::getName
StringRef getName() const
getName - Return the name of the corresponding LLVM function.
Definition: MachineFunction.cpp:542
llvm::MachineFunction::getConstantPool
MachineConstantPool * getConstantPool()
getConstantPool - Return the constant pool object for the current function.
Definition: MachineFunction.h:662
assert
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
llvm::MachineFunction::getFrameInfo
MachineFrameInfo & getFrameInfo()
getFrameInfo - Return the frame info object for the current function.
Definition: MachineFunction.h:646
llvm::MachineBasicBlock::getParent
const MachineFunction * getParent() const
Return the MachineFunction containing this basic block.
Definition: MachineBasicBlock.h:225
ARMBaseInstrInfo.h
llvm::MachineOperand::MO_TargetIndex
@ MO_TargetIndex
Target-dependent index+offset operand.
Definition: MachineOperand.h:59
llvm::gettBLXrOpcode
unsigned gettBLXrOpcode(const MachineFunction &MF)
Definition: ARMBaseInstrInfo.cpp:6554
llvm::MachineOperand::MO_FPImmediate
@ MO_FPImmediate
Floating-point immediate operand.
Definition: MachineOperand.h:55
llvm::MachineInstrBuilder::addReg
const MachineInstrBuilder & addReg(Register RegNo, unsigned flags=0, unsigned SubReg=0) const
Add a new virtual register operand.
Definition: MachineInstrBuilder.h:97
llvm::MachineOperand::getReg
Register getReg() const
getReg - Returns the register number.
Definition: MachineOperand.h:360
llvm::ARM_AM::isSOImmTwoPartVal
bool isSOImmTwoPartVal(unsigned V)
isSOImmTwoPartVal - Return true if the specified value can be obtained by or'ing together two SOImmVa...
Definition: ARMAddressingModes.h:180
R6
#define R6(n)
ARM.h
llvm::MachineFunction
Definition: MachineFunction.h:234
llvm::MachineOperand::MO_JumpTableIndex
@ MO_JumpTableIndex
Address of indexed Jump Table for switch.
Definition: MachineOperand.h:60
llvm::MachineOperand::MO_CImmediate
@ MO_CImmediate
Immediate >64bit operand.
Definition: MachineOperand.h:54
ARMAddressingModes.h
ARM_EXPAND_PSEUDO_NAME
#define ARM_EXPAND_PSEUDO_NAME
Definition: ARMExpandPseudoInsts.cpp:36
llvm::StringRef
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:58
llvm::MachineBasicBlock::rbegin
reverse_iterator rbegin()
Definition: MachineBasicBlock.h:272
llvm::MachineBasicBlock::splice
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 '...
Definition: MachineBasicBlock.h:950
MBBI
MachineBasicBlock MachineBasicBlock::iterator MBBI
Definition: AArch64SLSHardening.cpp:75
llvm_unreachable
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
Definition: ErrorHandling.h:134
llvm::ms_demangle::IntrinsicFunctionKind::New
@ New
llvm::MIBundleBuilder
Helper class for constructing bundles of MachineInstrs.
Definition: MachineInstrBuilder.h:544
llvm::MachineOperand::MO_MachineBasicBlock
@ MO_MachineBasicBlock
MachineBasicBlock reference.
Definition: MachineOperand.h:56
llvm::ilist_node_impl::getIterator
self_iterator getIterator()
Definition: ilist_node.h:81
DL
MachineBasicBlock MachineBasicBlock::iterator DebugLoc DL
Definition: AArch64SLSHardening.cpp:76
S
add sub stmia L5 ldr r0 bl L_printf $stub Instead of a and a wouldn t it be better to do three moves *Return an aggregate type is even return S
Definition: README.txt:210
llvm::MachineOperand::MO_IntrinsicID
@ MO_IntrinsicID
Intrinsic ID for ISel.
Definition: MachineOperand.h:69
llvm::Pass::dump
void dump() const
Definition: Pass.cpp:131
llvm::ARMBaseInstrInfo::getRegisterInfo
virtual const ARMBaseRegisterInfo & getRegisterInfo() const =0
llvm::MachineBasicBlock::transferSuccessors
void transferSuccessors(MachineBasicBlock *FromMBB)
Transfers all the successors from MBB to this machine basic block (i.e., copies all the successors Fr...
Definition: MachineBasicBlock.cpp:870
llvm::MachineInstrBuilder::getInstr
MachineInstr * getInstr() const
If conversion operators fail, use this method to get the MachineInstr explicitly.
Definition: MachineInstrBuilder.h:89
llvm::MachineFrameInfo::getMaxAlign
Align getMaxAlign() const
Return the alignment in bytes that this function must be aligned to, which is greater than the defaul...
Definition: MachineFrameInfo.h:569
llvm::Register
Wrapper class representing virtual and physical registers.
Definition: Register.h:19
llvm::MachineBasicBlock::addLiveIn
void addLiveIn(MCRegister PhysReg, LaneBitmask LaneMask=LaneBitmask::getAll())
Adds the specified register as a live in.
Definition: MachineBasicBlock.h:367
llvm::ARMBaseRegisterInfo
Definition: ARMBaseRegisterInfo.h:100
MBB
MachineBasicBlock & MBB
Definition: AArch64SLSHardening.cpp:74
LookupNEONLdSt
static const NEONLdStTableEntry * LookupNEONLdSt(unsigned Opcode)
LookupNEONLdSt - Search the NEONLdStTable for information about a NEON load or store pseudo instructi...
Definition: ARMExpandPseudoInsts.cpp:514
llvm::MachineFunction::getFunction
Function & getFunction()
Return the LLVM function that this machine code represents.
Definition: MachineFunction.h:596
llvm::ARMII::MO_LO16
@ MO_LO16
MO_LO16 - On a symbol operand, this represents a relocation containing lower 16 bit of the address.
Definition: ARMBaseInfo.h:246
llvm::TargetSubtargetInfo::getFrameLowering
virtual const TargetFrameLowering * getFrameLowering() const
Definition: TargetSubtargetInfo.h:93
uint16_t
llvm::ARMConstantPoolConstant::Create
static ARMConstantPoolConstant * Create(const Constant *C, unsigned ID)
Definition: ARMConstantPoolValue.cpp:148
llvm::AMDGPU::SendMsg::Op
Op
Definition: SIDefines.h:324
llvm::set_difference
S1Ty set_difference(const S1Ty &S1, const S2Ty &S2)
set_difference(A, B) - Return A - B
Definition: SetOperations.h:50
MachineFrameInfo.h
llvm::Align::value
uint64_t value() const
This is a hole in the type system and should not be abused.
Definition: Alignment.h:85
llvm::MachineOperand::MO_ExternalSymbol
@ MO_ExternalSymbol
Name of external global symbol.
Definition: MachineOperand.h:61
llvm::MachineInstrBuilder::addConstantPoolIndex
const MachineInstrBuilder & addConstantPoolIndex(unsigned Idx, int Offset=0, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:158
llvm::sort
void sort(IteratorTy Start, IteratorTy End)
Definition: STLExtras.h:1492
determineGPRegsToClear
static void determineGPRegsToClear(const MachineInstr &MI, const std::initializer_list< unsigned > &Regs, SmallVectorImpl< unsigned > &ClearRegs)
Definition: ARMExpandPseudoInsts.cpp:1091
llvm::is_sorted
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...
Definition: STLExtras.h:1622
llvm::MachineOperand::setImplicit
void setImplicit(bool Val=true)
Definition: MachineOperand.h:495
llvm::ARMCC::CondCodes
CondCodes
Definition: ARMBaseInfo.h:30
llvm::ARM_AM::getSORegOpc
unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
Definition: ARMAddressingModes.h:112
llvm::MachineOperand::isImm
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
Definition: MachineOperand.h:323
llvm::BitVector::reset
BitVector & reset()
Definition: BitVector.h:384
llvm::MachineInstrBuilder::addGlobalAddress
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned TargetFlags=0) const
Definition: MachineInstrBuilder.h:177
llvm::getKillRegState
unsigned getKillRegState(bool B)
Definition: MachineInstrBuilder.h:508
llvm::MachineFrameInfo
The MachineFrameInfo class represents an abstract stack frame until prolog/epilog code is inserted.
Definition: MachineFrameInfo.h:107
llvm::MachineBasicBlock::begin
iterator begin()
Definition: MachineBasicBlock.h:268
llvm::MachineOperand::getSymbolName
const char * getSymbolName() const
Definition: MachineOperand.h:608
llvm::MachineInstrBuilder::setMIFlags
const MachineInstrBuilder & setMIFlags(unsigned Flags) const
Definition: MachineInstrBuilder.h:273
llvm::BuildMI
MachineInstrBuilder BuildMI(MachineFunction &MF, const DebugLoc &DL, const MCInstrDesc &MCID)
Builder interface. Specify how to create the initial instruction itself.
Definition: MachineInstrBuilder.h:328
DefMI
MachineInstrBuilder MachineInstrBuilder & DefMI
Definition: AArch64ExpandPseudoInsts.cpp:103
llvm::emitARMRegPlusImmediate
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...
Definition: ARMBaseInstrInfo.cpp:2486
llvm::emitThumbRegPlusImmediate
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...
Definition: ThumbRegisterInfo.cpp:185
llvm::InlineAsm::Extra_HasSideEffects
@ Extra_HasSideEffects
Definition: InlineAsm.h:223
llvm::MachineInstr::addOperand
void addOperand(MachineFunction &MF, const MachineOperand &Op)
Add the specified operand to the instruction.
Definition: MachineInstr.cpp:207
llvm::AArch64_AM::UXTB
@ UXTB
Definition: AArch64AddressingModes.h:41
llvm::SmallVectorImpl< unsigned >
llvm::ARMBaseRegisterInfo::hasBasePointer
bool hasBasePointer(const MachineFunction &MF) const
Definition: ARMBaseRegisterInfo.cpp:410
llvm::ARMII::MO_GOT
@ MO_GOT
MO_GOT - On a symbol operand, this represents a GOT relative relocation.
Definition: ARMBaseInfo.h:262
llvm::TargetRegisterInfo::getSubReg
MCRegister getSubReg(MCRegister Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo.
Definition: TargetRegisterInfo.h:1094
llvm::FunctionPass
FunctionPass class - This class is used to implement most global optimizations.
Definition: Pass.h:298
llvm::predOps
static std::array< MachineOperand, 2 > predOps(ARMCC::CondCodes Pred, unsigned PredReg=0)
Get the operands corresponding to the given Pred value.
Definition: ARMBaseInstrInfo.h:540
llvm::AArch64_AM::UXTH
@ UXTH
Definition: AArch64AddressingModes.h:42
llvm::DebugLoc
A debug info location.
Definition: DebugLoc.h:33
llvm::MachineOperand::MO_RegisterMask
@ MO_RegisterMask
Mask of preserved registers.
Definition: MachineOperand.h:64
llvm::cl::desc
Definition: CommandLine.h:412
llvm::MachineInstrBundleIterator< MachineInstr >
llvm::MCInstrDesc::getNumOperands
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction.
Definition: MCInstrDesc.h:228
Debug.h
llvm::ARMCP::CPValue
@ CPValue
Definition: ARMConstantPoolValue.h:38
llvm::MachineBasicBlock::end
iterator end()
Definition: MachineBasicBlock.h:270
SubReg
unsigned SubReg
Definition: AArch64AdvSIMDScalarPass.cpp:104
llvm::ARM_AM::asr
@ asr
Definition: ARMAddressingModes.h:29
llvm::MachineOperand::isGlobal
bool isGlobal() const
isGlobal - Tests if this is a MO_GlobalAddress operand.
Definition: MachineOperand.h:339
llvm::Intrinsic::ID
unsigned ID
Definition: TargetTransformInfo.h:37
llvm::MachineOperand::MO_ConstantPoolIndex
@ MO_ConstantPoolIndex
Address of indexed Constant in Constant Pool.
Definition: MachineOperand.h:58
LivePhysRegs.h