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