LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
ARMExpandPseudoInsts.cpp
Go to the documentation of this file.
1 //===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -------------===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains a pass that expands pseudo instructions into target
11 // instructions to allow proper scheduling, if-conversion, and other late
12 // optimizations. This pass should be run after register allocation but before
13 // the post-regalloc scheduling pass.
14 //
15 //===----------------------------------------------------------------------===//
16 
17 #define DEBUG_TYPE "arm-pseudo"
18 #include "ARM.h"
19 #include "ARMBaseInstrInfo.h"
20 #include "ARMBaseRegisterInfo.h"
21 #include "ARMMachineFunctionInfo.h"
27 #include "llvm/Support/raw_ostream.h" // FIXME: for debug only. remove!
30 using namespace llvm;
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 namespace {
37  class ARMExpandPseudo : public MachineFunctionPass {
38  public:
39  static char ID;
40  ARMExpandPseudo() : MachineFunctionPass(ID) {}
41 
42  const ARMBaseInstrInfo *TII;
43  const TargetRegisterInfo *TRI;
44  const ARMSubtarget *STI;
45  ARMFunctionInfo *AFI;
46 
47  virtual bool runOnMachineFunction(MachineFunction &Fn);
48 
49  virtual const char *getPassName() const {
50  return "ARM pseudo instruction expansion pass";
51  }
52 
53  private:
54  void TransferImpOps(MachineInstr &OldMI,
56  bool ExpandMI(MachineBasicBlock &MBB,
58  bool ExpandMBB(MachineBasicBlock &MBB);
59  void ExpandVLD(MachineBasicBlock::iterator &MBBI);
60  void ExpandVST(MachineBasicBlock::iterator &MBBI);
61  void ExpandLaneOp(MachineBasicBlock::iterator &MBBI);
62  void ExpandVTBL(MachineBasicBlock::iterator &MBBI,
63  unsigned Opc, bool IsExt);
64  void ExpandMOV32BitImm(MachineBasicBlock &MBB,
66  };
67  char ARMExpandPseudo::ID = 0;
68 }
69 
70 /// TransferImpOps - Transfer implicit operands on the pseudo instruction to
71 /// the instructions created from the expansion.
72 void ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI,
73  MachineInstrBuilder &UseMI,
74  MachineInstrBuilder &DefMI) {
75  const MCInstrDesc &Desc = OldMI.getDesc();
76  for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands();
77  i != e; ++i) {
78  const MachineOperand &MO = OldMI.getOperand(i);
79  assert(MO.isReg() && MO.getReg());
80  if (MO.isUse())
81  UseMI.addOperand(MO);
82  else
83  DefMI.addOperand(MO);
84  }
85 }
86 
87 namespace {
88  // Constants for register spacing in NEON load/store instructions.
89  // For quad-register load-lane and store-lane pseudo instructors, the
90  // spacing is initially assumed to be EvenDblSpc, and that is changed to
91  // OddDblSpc depending on the lane number operand.
93  SingleSpc,
94  EvenDblSpc,
95  OddDblSpc
96  };
97 
98  // Entries for NEON load/store information table. The table is sorted by
99  // PseudoOpc for fast binary-search lookups.
100  struct NEONLdStTableEntry {
101  uint16_t PseudoOpc;
102  uint16_t RealOpc;
103  bool IsLoad;
104  bool isUpdating;
105  bool hasWritebackOperand;
106  uint8_t RegSpacing; // One of type NEONRegSpacing
107  uint8_t NumRegs; // D registers loaded or stored
108  uint8_t RegElts; // elements per D register; used for lane ops
109  // FIXME: Temporary flag to denote whether the real instruction takes
110  // a single register (like the encoding) or all of the registers in
111  // the list (like the asm syntax and the isel DAG). When all definitions
112  // are converted to take only the single encoded register, this will
113  // go away.
114  bool copyAllListRegs;
115 
116  // Comparison methods for binary search of the table.
117  bool operator<(const NEONLdStTableEntry &TE) const {
118  return PseudoOpc < TE.PseudoOpc;
119  }
120  friend bool operator<(const NEONLdStTableEntry &TE, unsigned PseudoOpc) {
121  return TE.PseudoOpc < PseudoOpc;
122  }
123  friend bool LLVM_ATTRIBUTE_UNUSED operator<(unsigned PseudoOpc,
124  const NEONLdStTableEntry &TE) {
125  return PseudoOpc < TE.PseudoOpc;
126  }
127  };
128 }
129 
130 static const NEONLdStTableEntry NEONLdStTable[] = {
131 { ARM::VLD1LNq16Pseudo, ARM::VLD1LNd16, true, false, false, EvenDblSpc, 1, 4 ,true},
132 { ARM::VLD1LNq16Pseudo_UPD, ARM::VLD1LNd16_UPD, true, true, true, EvenDblSpc, 1, 4 ,true},
133 { ARM::VLD1LNq32Pseudo, ARM::VLD1LNd32, true, false, false, EvenDblSpc, 1, 2 ,true},
134 { ARM::VLD1LNq32Pseudo_UPD, ARM::VLD1LNd32_UPD, true, true, true, EvenDblSpc, 1, 2 ,true},
135 { ARM::VLD1LNq8Pseudo, ARM::VLD1LNd8, true, false, false, EvenDblSpc, 1, 8 ,true},
136 { ARM::VLD1LNq8Pseudo_UPD, ARM::VLD1LNd8_UPD, true, true, true, EvenDblSpc, 1, 8 ,true},
137 
138 { ARM::VLD1d64QPseudo, ARM::VLD1d64Q, true, false, false, SingleSpc, 4, 1 ,false},
139 { ARM::VLD1d64TPseudo, ARM::VLD1d64T, true, false, false, SingleSpc, 3, 1 ,false},
140 
141 { ARM::VLD2LNd16Pseudo, ARM::VLD2LNd16, true, false, false, SingleSpc, 2, 4 ,true},
142 { ARM::VLD2LNd16Pseudo_UPD, ARM::VLD2LNd16_UPD, true, true, true, SingleSpc, 2, 4 ,true},
143 { ARM::VLD2LNd32Pseudo, ARM::VLD2LNd32, true, false, false, SingleSpc, 2, 2 ,true},
144 { ARM::VLD2LNd32Pseudo_UPD, ARM::VLD2LNd32_UPD, true, true, true, SingleSpc, 2, 2 ,true},
145 { ARM::VLD2LNd8Pseudo, ARM::VLD2LNd8, true, false, false, SingleSpc, 2, 8 ,true},
146 { ARM::VLD2LNd8Pseudo_UPD, ARM::VLD2LNd8_UPD, true, true, true, SingleSpc, 2, 8 ,true},
147 { ARM::VLD2LNq16Pseudo, ARM::VLD2LNq16, true, false, false, EvenDblSpc, 2, 4 ,true},
148 { ARM::VLD2LNq16Pseudo_UPD, ARM::VLD2LNq16_UPD, true, true, true, EvenDblSpc, 2, 4 ,true},
149 { ARM::VLD2LNq32Pseudo, ARM::VLD2LNq32, true, false, false, EvenDblSpc, 2, 2 ,true},
150 { ARM::VLD2LNq32Pseudo_UPD, ARM::VLD2LNq32_UPD, true, true, true, EvenDblSpc, 2, 2 ,true},
151 
152 { ARM::VLD2q16Pseudo, ARM::VLD2q16, true, false, false, SingleSpc, 4, 4 ,false},
153 { ARM::VLD2q16PseudoWB_fixed, ARM::VLD2q16wb_fixed, true, true, false, SingleSpc, 4, 4 ,false},
154 { ARM::VLD2q16PseudoWB_register, ARM::VLD2q16wb_register, true, true, true, SingleSpc, 4, 4 ,false},
155 { ARM::VLD2q32Pseudo, ARM::VLD2q32, true, false, false, SingleSpc, 4, 2 ,false},
156 { ARM::VLD2q32PseudoWB_fixed, ARM::VLD2q32wb_fixed, true, true, false, SingleSpc, 4, 2 ,false},
157 { ARM::VLD2q32PseudoWB_register, ARM::VLD2q32wb_register, true, true, true, SingleSpc, 4, 2 ,false},
158 { ARM::VLD2q8Pseudo, ARM::VLD2q8, true, false, false, SingleSpc, 4, 8 ,false},
159 { ARM::VLD2q8PseudoWB_fixed, ARM::VLD2q8wb_fixed, true, true, false, SingleSpc, 4, 8 ,false},
160 { ARM::VLD2q8PseudoWB_register, ARM::VLD2q8wb_register, true, true, true, SingleSpc, 4, 8 ,false},
161 
162 { ARM::VLD3DUPd16Pseudo, ARM::VLD3DUPd16, true, false, false, SingleSpc, 3, 4,true},
163 { ARM::VLD3DUPd16Pseudo_UPD, ARM::VLD3DUPd16_UPD, true, true, true, SingleSpc, 3, 4,true},
164 { ARM::VLD3DUPd32Pseudo, ARM::VLD3DUPd32, true, false, false, SingleSpc, 3, 2,true},
165 { ARM::VLD3DUPd32Pseudo_UPD, ARM::VLD3DUPd32_UPD, true, true, true, SingleSpc, 3, 2,true},
166 { ARM::VLD3DUPd8Pseudo, ARM::VLD3DUPd8, true, false, false, SingleSpc, 3, 8,true},
167 { ARM::VLD3DUPd8Pseudo_UPD, ARM::VLD3DUPd8_UPD, true, true, true, SingleSpc, 3, 8,true},
168 
169 { ARM::VLD3LNd16Pseudo, ARM::VLD3LNd16, true, false, false, SingleSpc, 3, 4 ,true},
170 { ARM::VLD3LNd16Pseudo_UPD, ARM::VLD3LNd16_UPD, true, true, true, SingleSpc, 3, 4 ,true},
171 { ARM::VLD3LNd32Pseudo, ARM::VLD3LNd32, true, false, false, SingleSpc, 3, 2 ,true},
172 { ARM::VLD3LNd32Pseudo_UPD, ARM::VLD3LNd32_UPD, true, true, true, SingleSpc, 3, 2 ,true},
173 { ARM::VLD3LNd8Pseudo, ARM::VLD3LNd8, true, false, false, SingleSpc, 3, 8 ,true},
174 { ARM::VLD3LNd8Pseudo_UPD, ARM::VLD3LNd8_UPD, true, true, true, SingleSpc, 3, 8 ,true},
175 { ARM::VLD3LNq16Pseudo, ARM::VLD3LNq16, true, false, false, EvenDblSpc, 3, 4 ,true},
176 { ARM::VLD3LNq16Pseudo_UPD, ARM::VLD3LNq16_UPD, true, true, true, EvenDblSpc, 3, 4 ,true},
177 { ARM::VLD3LNq32Pseudo, ARM::VLD3LNq32, true, false, false, EvenDblSpc, 3, 2 ,true},
178 { ARM::VLD3LNq32Pseudo_UPD, ARM::VLD3LNq32_UPD, true, true, true, EvenDblSpc, 3, 2 ,true},
179 
180 { ARM::VLD3d16Pseudo, ARM::VLD3d16, true, false, false, SingleSpc, 3, 4 ,true},
181 { ARM::VLD3d16Pseudo_UPD, ARM::VLD3d16_UPD, true, true, true, SingleSpc, 3, 4 ,true},
182 { ARM::VLD3d32Pseudo, ARM::VLD3d32, true, false, false, SingleSpc, 3, 2 ,true},
183 { ARM::VLD3d32Pseudo_UPD, ARM::VLD3d32_UPD, true, true, true, SingleSpc, 3, 2 ,true},
184 { ARM::VLD3d8Pseudo, ARM::VLD3d8, true, false, false, SingleSpc, 3, 8 ,true},
185 { ARM::VLD3d8Pseudo_UPD, ARM::VLD3d8_UPD, true, true, true, SingleSpc, 3, 8 ,true},
186 
187 { ARM::VLD3q16Pseudo_UPD, ARM::VLD3q16_UPD, true, true, true, EvenDblSpc, 3, 4 ,true},
188 { ARM::VLD3q16oddPseudo, ARM::VLD3q16, true, false, false, OddDblSpc, 3, 4 ,true},
189 { ARM::VLD3q16oddPseudo_UPD, ARM::VLD3q16_UPD, true, true, true, OddDblSpc, 3, 4 ,true},
190 { ARM::VLD3q32Pseudo_UPD, ARM::VLD3q32_UPD, true, true, true, EvenDblSpc, 3, 2 ,true},
191 { ARM::VLD3q32oddPseudo, ARM::VLD3q32, true, false, false, OddDblSpc, 3, 2 ,true},
192 { ARM::VLD3q32oddPseudo_UPD, ARM::VLD3q32_UPD, true, true, true, OddDblSpc, 3, 2 ,true},
193 { ARM::VLD3q8Pseudo_UPD, ARM::VLD3q8_UPD, true, true, true, EvenDblSpc, 3, 8 ,true},
194 { ARM::VLD3q8oddPseudo, ARM::VLD3q8, true, false, false, OddDblSpc, 3, 8 ,true},
195 { ARM::VLD3q8oddPseudo_UPD, ARM::VLD3q8_UPD, true, true, true, OddDblSpc, 3, 8 ,true},
196 
197 { ARM::VLD4DUPd16Pseudo, ARM::VLD4DUPd16, true, false, false, SingleSpc, 4, 4,true},
198 { ARM::VLD4DUPd16Pseudo_UPD, ARM::VLD4DUPd16_UPD, true, true, true, SingleSpc, 4, 4,true},
199 { ARM::VLD4DUPd32Pseudo, ARM::VLD4DUPd32, true, false, false, SingleSpc, 4, 2,true},
200 { ARM::VLD4DUPd32Pseudo_UPD, ARM::VLD4DUPd32_UPD, true, true, true, SingleSpc, 4, 2,true},
201 { ARM::VLD4DUPd8Pseudo, ARM::VLD4DUPd8, true, false, false, SingleSpc, 4, 8,true},
202 { ARM::VLD4DUPd8Pseudo_UPD, ARM::VLD4DUPd8_UPD, true, true, true, SingleSpc, 4, 8,true},
203 
204 { ARM::VLD4LNd16Pseudo, ARM::VLD4LNd16, true, false, false, SingleSpc, 4, 4 ,true},
205 { ARM::VLD4LNd16Pseudo_UPD, ARM::VLD4LNd16_UPD, true, true, true, SingleSpc, 4, 4 ,true},
206 { ARM::VLD4LNd32Pseudo, ARM::VLD4LNd32, true, false, false, SingleSpc, 4, 2 ,true},
207 { ARM::VLD4LNd32Pseudo_UPD, ARM::VLD4LNd32_UPD, true, true, true, SingleSpc, 4, 2 ,true},
208 { ARM::VLD4LNd8Pseudo, ARM::VLD4LNd8, true, false, false, SingleSpc, 4, 8 ,true},
209 { ARM::VLD4LNd8Pseudo_UPD, ARM::VLD4LNd8_UPD, true, true, true, SingleSpc, 4, 8 ,true},
210 { ARM::VLD4LNq16Pseudo, ARM::VLD4LNq16, true, false, false, EvenDblSpc, 4, 4 ,true},
211 { ARM::VLD4LNq16Pseudo_UPD, ARM::VLD4LNq16_UPD, true, true, true, EvenDblSpc, 4, 4 ,true},
212 { ARM::VLD4LNq32Pseudo, ARM::VLD4LNq32, true, false, false, EvenDblSpc, 4, 2 ,true},
213 { ARM::VLD4LNq32Pseudo_UPD, ARM::VLD4LNq32_UPD, true, true, true, EvenDblSpc, 4, 2 ,true},
214 
215 { ARM::VLD4d16Pseudo, ARM::VLD4d16, true, false, false, SingleSpc, 4, 4 ,true},
216 { ARM::VLD4d16Pseudo_UPD, ARM::VLD4d16_UPD, true, true, true, SingleSpc, 4, 4 ,true},
217 { ARM::VLD4d32Pseudo, ARM::VLD4d32, true, false, false, SingleSpc, 4, 2 ,true},
218 { ARM::VLD4d32Pseudo_UPD, ARM::VLD4d32_UPD, true, true, true, SingleSpc, 4, 2 ,true},
219 { ARM::VLD4d8Pseudo, ARM::VLD4d8, true, false, false, SingleSpc, 4, 8 ,true},
220 { ARM::VLD4d8Pseudo_UPD, ARM::VLD4d8_UPD, true, true, true, SingleSpc, 4, 8 ,true},
221 
222 { ARM::VLD4q16Pseudo_UPD, ARM::VLD4q16_UPD, true, true, true, EvenDblSpc, 4, 4 ,true},
223 { ARM::VLD4q16oddPseudo, ARM::VLD4q16, true, false, false, OddDblSpc, 4, 4 ,true},
224 { ARM::VLD4q16oddPseudo_UPD, ARM::VLD4q16_UPD, true, true, true, OddDblSpc, 4, 4 ,true},
225 { ARM::VLD4q32Pseudo_UPD, ARM::VLD4q32_UPD, true, true, true, EvenDblSpc, 4, 2 ,true},
226 { ARM::VLD4q32oddPseudo, ARM::VLD4q32, true, false, false, OddDblSpc, 4, 2 ,true},
227 { ARM::VLD4q32oddPseudo_UPD, ARM::VLD4q32_UPD, true, true, true, OddDblSpc, 4, 2 ,true},
228 { ARM::VLD4q8Pseudo_UPD, ARM::VLD4q8_UPD, true, true, true, EvenDblSpc, 4, 8 ,true},
229 { ARM::VLD4q8oddPseudo, ARM::VLD4q8, true, false, false, OddDblSpc, 4, 8 ,true},
230 { ARM::VLD4q8oddPseudo_UPD, ARM::VLD4q8_UPD, true, true, true, OddDblSpc, 4, 8 ,true},
231 
232 { ARM::VST1LNq16Pseudo, ARM::VST1LNd16, false, false, false, EvenDblSpc, 1, 4 ,true},
233 { ARM::VST1LNq16Pseudo_UPD, ARM::VST1LNd16_UPD, false, true, true, EvenDblSpc, 1, 4 ,true},
234 { ARM::VST1LNq32Pseudo, ARM::VST1LNd32, false, false, false, EvenDblSpc, 1, 2 ,true},
235 { ARM::VST1LNq32Pseudo_UPD, ARM::VST1LNd32_UPD, false, true, true, EvenDblSpc, 1, 2 ,true},
236 { ARM::VST1LNq8Pseudo, ARM::VST1LNd8, false, false, false, EvenDblSpc, 1, 8 ,true},
237 { ARM::VST1LNq8Pseudo_UPD, ARM::VST1LNd8_UPD, false, true, true, EvenDblSpc, 1, 8 ,true},
238 
239 { ARM::VST1d64QPseudo, ARM::VST1d64Q, false, false, false, SingleSpc, 4, 1 ,false},
240 { ARM::VST1d64QPseudoWB_fixed, ARM::VST1d64Qwb_fixed, false, true, false, SingleSpc, 4, 1 ,false},
241 { ARM::VST1d64QPseudoWB_register, ARM::VST1d64Qwb_register, false, true, true, SingleSpc, 4, 1 ,false},
242 { ARM::VST1d64TPseudo, ARM::VST1d64T, false, false, false, SingleSpc, 3, 1 ,false},
243 { ARM::VST1d64TPseudoWB_fixed, ARM::VST1d64Twb_fixed, false, true, false, SingleSpc, 3, 1 ,false},
244 { ARM::VST1d64TPseudoWB_register, ARM::VST1d64Twb_register, false, true, true, SingleSpc, 3, 1 ,false},
245 
246 { ARM::VST2LNd16Pseudo, ARM::VST2LNd16, false, false, false, SingleSpc, 2, 4 ,true},
247 { ARM::VST2LNd16Pseudo_UPD, ARM::VST2LNd16_UPD, false, true, true, SingleSpc, 2, 4 ,true},
248 { ARM::VST2LNd32Pseudo, ARM::VST2LNd32, false, false, false, SingleSpc, 2, 2 ,true},
249 { ARM::VST2LNd32Pseudo_UPD, ARM::VST2LNd32_UPD, false, true, true, SingleSpc, 2, 2 ,true},
250 { ARM::VST2LNd8Pseudo, ARM::VST2LNd8, false, false, false, SingleSpc, 2, 8 ,true},
251 { ARM::VST2LNd8Pseudo_UPD, ARM::VST2LNd8_UPD, false, true, true, SingleSpc, 2, 8 ,true},
252 { ARM::VST2LNq16Pseudo, ARM::VST2LNq16, false, false, false, EvenDblSpc, 2, 4,true},
253 { ARM::VST2LNq16Pseudo_UPD, ARM::VST2LNq16_UPD, false, true, true, EvenDblSpc, 2, 4,true},
254 { ARM::VST2LNq32Pseudo, ARM::VST2LNq32, false, false, false, EvenDblSpc, 2, 2,true},
255 { ARM::VST2LNq32Pseudo_UPD, ARM::VST2LNq32_UPD, false, true, true, EvenDblSpc, 2, 2,true},
256 
257 { ARM::VST2q16Pseudo, ARM::VST2q16, false, false, false, SingleSpc, 4, 4 ,false},
258 { ARM::VST2q16PseudoWB_fixed, ARM::VST2q16wb_fixed, false, true, false, SingleSpc, 4, 4 ,false},
259 { ARM::VST2q16PseudoWB_register, ARM::VST2q16wb_register, false, true, true, SingleSpc, 4, 4 ,false},
260 { ARM::VST2q32Pseudo, ARM::VST2q32, false, false, false, SingleSpc, 4, 2 ,false},
261 { ARM::VST2q32PseudoWB_fixed, ARM::VST2q32wb_fixed, false, true, false, SingleSpc, 4, 2 ,false},
262 { ARM::VST2q32PseudoWB_register, ARM::VST2q32wb_register, false, true, true, SingleSpc, 4, 2 ,false},
263 { ARM::VST2q8Pseudo, ARM::VST2q8, false, false, false, SingleSpc, 4, 8 ,false},
264 { ARM::VST2q8PseudoWB_fixed, ARM::VST2q8wb_fixed, false, true, false, SingleSpc, 4, 8 ,false},
265 { ARM::VST2q8PseudoWB_register, ARM::VST2q8wb_register, false, true, true, SingleSpc, 4, 8 ,false},
266 
267 { ARM::VST3LNd16Pseudo, ARM::VST3LNd16, false, false, false, SingleSpc, 3, 4 ,true},
268 { ARM::VST3LNd16Pseudo_UPD, ARM::VST3LNd16_UPD, false, true, true, SingleSpc, 3, 4 ,true},
269 { ARM::VST3LNd32Pseudo, ARM::VST3LNd32, false, false, false, SingleSpc, 3, 2 ,true},
270 { ARM::VST3LNd32Pseudo_UPD, ARM::VST3LNd32_UPD, false, true, true, SingleSpc, 3, 2 ,true},
271 { ARM::VST3LNd8Pseudo, ARM::VST3LNd8, false, false, false, SingleSpc, 3, 8 ,true},
272 { ARM::VST3LNd8Pseudo_UPD, ARM::VST3LNd8_UPD, false, true, true, SingleSpc, 3, 8 ,true},
273 { ARM::VST3LNq16Pseudo, ARM::VST3LNq16, false, false, false, EvenDblSpc, 3, 4,true},
274 { ARM::VST3LNq16Pseudo_UPD, ARM::VST3LNq16_UPD, false, true, true, EvenDblSpc, 3, 4,true},
275 { ARM::VST3LNq32Pseudo, ARM::VST3LNq32, false, false, false, EvenDblSpc, 3, 2,true},
276 { ARM::VST3LNq32Pseudo_UPD, ARM::VST3LNq32_UPD, false, true, true, EvenDblSpc, 3, 2,true},
277 
278 { ARM::VST3d16Pseudo, ARM::VST3d16, false, false, false, SingleSpc, 3, 4 ,true},
279 { ARM::VST3d16Pseudo_UPD, ARM::VST3d16_UPD, false, true, true, SingleSpc, 3, 4 ,true},
280 { ARM::VST3d32Pseudo, ARM::VST3d32, false, false, false, SingleSpc, 3, 2 ,true},
281 { ARM::VST3d32Pseudo_UPD, ARM::VST3d32_UPD, false, true, true, SingleSpc, 3, 2 ,true},
282 { ARM::VST3d8Pseudo, ARM::VST3d8, false, false, false, SingleSpc, 3, 8 ,true},
283 { ARM::VST3d8Pseudo_UPD, ARM::VST3d8_UPD, false, true, true, SingleSpc, 3, 8 ,true},
284 
285 { ARM::VST3q16Pseudo_UPD, ARM::VST3q16_UPD, false, true, true, EvenDblSpc, 3, 4 ,true},
286 { ARM::VST3q16oddPseudo, ARM::VST3q16, false, false, false, OddDblSpc, 3, 4 ,true},
287 { ARM::VST3q16oddPseudo_UPD, ARM::VST3q16_UPD, false, true, true, OddDblSpc, 3, 4 ,true},
288 { ARM::VST3q32Pseudo_UPD, ARM::VST3q32_UPD, false, true, true, EvenDblSpc, 3, 2 ,true},
289 { ARM::VST3q32oddPseudo, ARM::VST3q32, false, false, false, OddDblSpc, 3, 2 ,true},
290 { ARM::VST3q32oddPseudo_UPD, ARM::VST3q32_UPD, false, true, true, OddDblSpc, 3, 2 ,true},
291 { ARM::VST3q8Pseudo_UPD, ARM::VST3q8_UPD, false, true, true, EvenDblSpc, 3, 8 ,true},
292 { ARM::VST3q8oddPseudo, ARM::VST3q8, false, false, false, OddDblSpc, 3, 8 ,true},
293 { ARM::VST3q8oddPseudo_UPD, ARM::VST3q8_UPD, false, true, true, OddDblSpc, 3, 8 ,true},
294 
295 { ARM::VST4LNd16Pseudo, ARM::VST4LNd16, false, false, false, SingleSpc, 4, 4 ,true},
296 { ARM::VST4LNd16Pseudo_UPD, ARM::VST4LNd16_UPD, false, true, true, SingleSpc, 4, 4 ,true},
297 { ARM::VST4LNd32Pseudo, ARM::VST4LNd32, false, false, false, SingleSpc, 4, 2 ,true},
298 { ARM::VST4LNd32Pseudo_UPD, ARM::VST4LNd32_UPD, false, true, true, SingleSpc, 4, 2 ,true},
299 { ARM::VST4LNd8Pseudo, ARM::VST4LNd8, false, false, false, SingleSpc, 4, 8 ,true},
300 { ARM::VST4LNd8Pseudo_UPD, ARM::VST4LNd8_UPD, false, true, true, SingleSpc, 4, 8 ,true},
301 { ARM::VST4LNq16Pseudo, ARM::VST4LNq16, false, false, false, EvenDblSpc, 4, 4,true},
302 { ARM::VST4LNq16Pseudo_UPD, ARM::VST4LNq16_UPD, false, true, true, EvenDblSpc, 4, 4,true},
303 { ARM::VST4LNq32Pseudo, ARM::VST4LNq32, false, false, false, EvenDblSpc, 4, 2,true},
304 { ARM::VST4LNq32Pseudo_UPD, ARM::VST4LNq32_UPD, false, true, true, EvenDblSpc, 4, 2,true},
305 
306 { ARM::VST4d16Pseudo, ARM::VST4d16, false, false, false, SingleSpc, 4, 4 ,true},
307 { ARM::VST4d16Pseudo_UPD, ARM::VST4d16_UPD, false, true, true, SingleSpc, 4, 4 ,true},
308 { ARM::VST4d32Pseudo, ARM::VST4d32, false, false, false, SingleSpc, 4, 2 ,true},
309 { ARM::VST4d32Pseudo_UPD, ARM::VST4d32_UPD, false, true, true, SingleSpc, 4, 2 ,true},
310 { ARM::VST4d8Pseudo, ARM::VST4d8, false, false, false, SingleSpc, 4, 8 ,true},
311 { ARM::VST4d8Pseudo_UPD, ARM::VST4d8_UPD, false, true, true, SingleSpc, 4, 8 ,true},
312 
313 { ARM::VST4q16Pseudo_UPD, ARM::VST4q16_UPD, false, true, true, EvenDblSpc, 4, 4 ,true},
314 { ARM::VST4q16oddPseudo, ARM::VST4q16, false, false, false, OddDblSpc, 4, 4 ,true},
315 { ARM::VST4q16oddPseudo_UPD, ARM::VST4q16_UPD, false, true, true, OddDblSpc, 4, 4 ,true},
316 { ARM::VST4q32Pseudo_UPD, ARM::VST4q32_UPD, false, true, true, EvenDblSpc, 4, 2 ,true},
317 { ARM::VST4q32oddPseudo, ARM::VST4q32, false, false, false, OddDblSpc, 4, 2 ,true},
318 { ARM::VST4q32oddPseudo_UPD, ARM::VST4q32_UPD, false, true, true, OddDblSpc, 4, 2 ,true},
319 { ARM::VST4q8Pseudo_UPD, ARM::VST4q8_UPD, false, true, true, EvenDblSpc, 4, 8 ,true},
320 { ARM::VST4q8oddPseudo, ARM::VST4q8, false, false, false, OddDblSpc, 4, 8 ,true},
321 { ARM::VST4q8oddPseudo_UPD, ARM::VST4q8_UPD, false, true, true, OddDblSpc, 4, 8 ,true}
322 };
323 
324 /// LookupNEONLdSt - Search the NEONLdStTable for information about a NEON
325 /// load or store pseudo instruction.
326 static const NEONLdStTableEntry *LookupNEONLdSt(unsigned Opcode) {
327  const unsigned NumEntries = array_lengthof(NEONLdStTable);
328 
329 #ifndef NDEBUG
330  // Make sure the table is sorted.
331  static bool TableChecked = false;
332  if (!TableChecked) {
333  for (unsigned i = 0; i != NumEntries-1; ++i)
334  assert(NEONLdStTable[i] < NEONLdStTable[i+1] &&
335  "NEONLdStTable is not sorted!");
336  TableChecked = true;
337  }
338 #endif
339 
340  const NEONLdStTableEntry *I =
341  std::lower_bound(NEONLdStTable, NEONLdStTable + NumEntries, Opcode);
342  if (I != NEONLdStTable + NumEntries && I->PseudoOpc == Opcode)
343  return I;
344  return NULL;
345 }
346 
347 /// GetDSubRegs - Get 4 D subregisters of a Q, QQ, or QQQQ register,
348 /// corresponding to the specified register spacing. Not all of the results
349 /// are necessarily valid, e.g., a Q register only has 2 D subregisters.
350 static void GetDSubRegs(unsigned Reg, NEONRegSpacing RegSpc,
351  const TargetRegisterInfo *TRI, unsigned &D0,
352  unsigned &D1, unsigned &D2, unsigned &D3) {
353  if (RegSpc == SingleSpc) {
354  D0 = TRI->getSubReg(Reg, ARM::dsub_0);
355  D1 = TRI->getSubReg(Reg, ARM::dsub_1);
356  D2 = TRI->getSubReg(Reg, ARM::dsub_2);
357  D3 = TRI->getSubReg(Reg, ARM::dsub_3);
358  } else if (RegSpc == EvenDblSpc) {
359  D0 = TRI->getSubReg(Reg, ARM::dsub_0);
360  D1 = TRI->getSubReg(Reg, ARM::dsub_2);
361  D2 = TRI->getSubReg(Reg, ARM::dsub_4);
362  D3 = TRI->getSubReg(Reg, ARM::dsub_6);
363  } else {
364  assert(RegSpc == OddDblSpc && "unknown register spacing");
365  D0 = TRI->getSubReg(Reg, ARM::dsub_1);
366  D1 = TRI->getSubReg(Reg, ARM::dsub_3);
367  D2 = TRI->getSubReg(Reg, ARM::dsub_5);
368  D3 = TRI->getSubReg(Reg, ARM::dsub_7);
369  }
370 }
371 
372 /// ExpandVLD - Translate VLD pseudo instructions with Q, QQ or QQQQ register
373 /// operands to real VLD instructions with D register operands.
374 void ARMExpandPseudo::ExpandVLD(MachineBasicBlock::iterator &MBBI) {
375  MachineInstr &MI = *MBBI;
376  MachineBasicBlock &MBB = *MI.getParent();
377 
378  const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode());
379  assert(TableEntry && TableEntry->IsLoad && "NEONLdStTable lookup failed");
380  NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
381  unsigned NumRegs = TableEntry->NumRegs;
382 
383  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
384  TII->get(TableEntry->RealOpc));
385  unsigned OpIdx = 0;
386 
387  bool DstIsDead = MI.getOperand(OpIdx).isDead();
388  unsigned DstReg = MI.getOperand(OpIdx++).getReg();
389  unsigned D0, D1, D2, D3;
390  GetDSubRegs(DstReg, RegSpc, TRI, D0, D1, D2, D3);
391  MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead));
392  if (NumRegs > 1 && TableEntry->copyAllListRegs)
393  MIB.addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
394  if (NumRegs > 2 && TableEntry->copyAllListRegs)
395  MIB.addReg(D2, RegState::Define | getDeadRegState(DstIsDead));
396  if (NumRegs > 3 && TableEntry->copyAllListRegs)
397  MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead));
398 
399  if (TableEntry->isUpdating)
400  MIB.addOperand(MI.getOperand(OpIdx++));
401 
402  // Copy the addrmode6 operands.
403  MIB.addOperand(MI.getOperand(OpIdx++));
404  MIB.addOperand(MI.getOperand(OpIdx++));
405  // Copy the am6offset operand.
406  if (TableEntry->hasWritebackOperand)
407  MIB.addOperand(MI.getOperand(OpIdx++));
408 
409  // For an instruction writing double-spaced subregs, the pseudo instruction
410  // has an extra operand that is a use of the super-register. Record the
411  // operand index and skip over it.
412  unsigned SrcOpIdx = 0;
413  if (RegSpc == EvenDblSpc || RegSpc == OddDblSpc)
414  SrcOpIdx = OpIdx++;
415 
416  // Copy the predicate operands.
417  MIB.addOperand(MI.getOperand(OpIdx++));
418  MIB.addOperand(MI.getOperand(OpIdx++));
419 
420  // Copy the super-register source operand used for double-spaced subregs over
421  // to the new instruction as an implicit operand.
422  if (SrcOpIdx != 0) {
423  MachineOperand MO = MI.getOperand(SrcOpIdx);
424  MO.setImplicit(true);
425  MIB.addOperand(MO);
426  }
427  // Add an implicit def for the super-register.
428  MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
429  TransferImpOps(MI, MIB, MIB);
430 
431  // Transfer memoperands.
432  MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
433 
434  MI.eraseFromParent();
435 }
436 
437 /// ExpandVST - Translate VST pseudo instructions with Q, QQ or QQQQ register
438 /// operands to real VST instructions with D register operands.
439 void ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator &MBBI) {
440  MachineInstr &MI = *MBBI;
441  MachineBasicBlock &MBB = *MI.getParent();
442 
443  const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode());
444  assert(TableEntry && !TableEntry->IsLoad && "NEONLdStTable lookup failed");
445  NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
446  unsigned NumRegs = TableEntry->NumRegs;
447 
448  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
449  TII->get(TableEntry->RealOpc));
450  unsigned OpIdx = 0;
451  if (TableEntry->isUpdating)
452  MIB.addOperand(MI.getOperand(OpIdx++));
453 
454  // Copy the addrmode6 operands.
455  MIB.addOperand(MI.getOperand(OpIdx++));
456  MIB.addOperand(MI.getOperand(OpIdx++));
457  // Copy the am6offset operand.
458  if (TableEntry->hasWritebackOperand)
459  MIB.addOperand(MI.getOperand(OpIdx++));
460 
461  bool SrcIsKill = MI.getOperand(OpIdx).isKill();
462  bool SrcIsUndef = MI.getOperand(OpIdx).isUndef();
463  unsigned SrcReg = MI.getOperand(OpIdx++).getReg();
464  unsigned D0, D1, D2, D3;
465  GetDSubRegs(SrcReg, RegSpc, TRI, D0, D1, D2, D3);
466  MIB.addReg(D0, getUndefRegState(SrcIsUndef));
467  if (NumRegs > 1 && TableEntry->copyAllListRegs)
468  MIB.addReg(D1, getUndefRegState(SrcIsUndef));
469  if (NumRegs > 2 && TableEntry->copyAllListRegs)
470  MIB.addReg(D2, getUndefRegState(SrcIsUndef));
471  if (NumRegs > 3 && TableEntry->copyAllListRegs)
472  MIB.addReg(D3, getUndefRegState(SrcIsUndef));
473 
474  // Copy the predicate operands.
475  MIB.addOperand(MI.getOperand(OpIdx++));
476  MIB.addOperand(MI.getOperand(OpIdx++));
477 
478  if (SrcIsKill && !SrcIsUndef) // Add an implicit kill for the super-reg.
479  MIB->addRegisterKilled(SrcReg, TRI, true);
480  TransferImpOps(MI, MIB, MIB);
481 
482  // Transfer memoperands.
483  MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
484 
485  MI.eraseFromParent();
486 }
487 
488 /// ExpandLaneOp - Translate VLD*LN and VST*LN instructions with Q, QQ or QQQQ
489 /// register operands to real instructions with D register operands.
490 void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator &MBBI) {
491  MachineInstr &MI = *MBBI;
492  MachineBasicBlock &MBB = *MI.getParent();
493 
494  const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode());
495  assert(TableEntry && "NEONLdStTable lookup failed");
496  NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing;
497  unsigned NumRegs = TableEntry->NumRegs;
498  unsigned RegElts = TableEntry->RegElts;
499 
500  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(),
501  TII->get(TableEntry->RealOpc));
502  unsigned OpIdx = 0;
503  // The lane operand is always the 3rd from last operand, before the 2
504  // predicate operands.
505  unsigned Lane = MI.getOperand(MI.getDesc().getNumOperands() - 3).getImm();
506 
507  // Adjust the lane and spacing as needed for Q registers.
508  assert(RegSpc != OddDblSpc && "unexpected register spacing for VLD/VST-lane");
509  if (RegSpc == EvenDblSpc && Lane >= RegElts) {
510  RegSpc = OddDblSpc;
511  Lane -= RegElts;
512  }
513  assert(Lane < RegElts && "out of range lane for VLD/VST-lane");
514 
515  unsigned D0 = 0, D1 = 0, D2 = 0, D3 = 0;
516  unsigned DstReg = 0;
517  bool DstIsDead = false;
518  if (TableEntry->IsLoad) {
519  DstIsDead = MI.getOperand(OpIdx).isDead();
520  DstReg = MI.getOperand(OpIdx++).getReg();
521  GetDSubRegs(DstReg, RegSpc, TRI, D0, D1, D2, D3);
522  MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead));
523  if (NumRegs > 1)
524  MIB.addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
525  if (NumRegs > 2)
526  MIB.addReg(D2, RegState::Define | getDeadRegState(DstIsDead));
527  if (NumRegs > 3)
528  MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead));
529  }
530 
531  if (TableEntry->isUpdating)
532  MIB.addOperand(MI.getOperand(OpIdx++));
533 
534  // Copy the addrmode6 operands.
535  MIB.addOperand(MI.getOperand(OpIdx++));
536  MIB.addOperand(MI.getOperand(OpIdx++));
537  // Copy the am6offset operand.
538  if (TableEntry->hasWritebackOperand)
539  MIB.addOperand(MI.getOperand(OpIdx++));
540 
541  // Grab the super-register source.
542  MachineOperand MO = MI.getOperand(OpIdx++);
543  if (!TableEntry->IsLoad)
544  GetDSubRegs(MO.getReg(), RegSpc, TRI, D0, D1, D2, D3);
545 
546  // Add the subregs as sources of the new instruction.
547  unsigned SrcFlags = (getUndefRegState(MO.isUndef()) |
548  getKillRegState(MO.isKill()));
549  MIB.addReg(D0, SrcFlags);
550  if (NumRegs > 1)
551  MIB.addReg(D1, SrcFlags);
552  if (NumRegs > 2)
553  MIB.addReg(D2, SrcFlags);
554  if (NumRegs > 3)
555  MIB.addReg(D3, SrcFlags);
556 
557  // Add the lane number operand.
558  MIB.addImm(Lane);
559  OpIdx += 1;
560 
561  // Copy the predicate operands.
562  MIB.addOperand(MI.getOperand(OpIdx++));
563  MIB.addOperand(MI.getOperand(OpIdx++));
564 
565  // Copy the super-register source to be an implicit source.
566  MO.setImplicit(true);
567  MIB.addOperand(MO);
568  if (TableEntry->IsLoad)
569  // Add an implicit def for the super-register.
570  MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
571  TransferImpOps(MI, MIB, MIB);
572  // Transfer memoperands.
573  MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
574  MI.eraseFromParent();
575 }
576 
577 /// ExpandVTBL - Translate VTBL and VTBX pseudo instructions with Q or QQ
578 /// register operands to real instructions with D register operands.
579 void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator &MBBI,
580  unsigned Opc, bool IsExt) {
581  MachineInstr &MI = *MBBI;
582  MachineBasicBlock &MBB = *MI.getParent();
583 
584  MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc));
585  unsigned OpIdx = 0;
586 
587  // Transfer the destination register operand.
588  MIB.addOperand(MI.getOperand(OpIdx++));
589  if (IsExt)
590  MIB.addOperand(MI.getOperand(OpIdx++));
591 
592  bool SrcIsKill = MI.getOperand(OpIdx).isKill();
593  unsigned SrcReg = MI.getOperand(OpIdx++).getReg();
594  unsigned D0, D1, D2, D3;
595  GetDSubRegs(SrcReg, SingleSpc, TRI, D0, D1, D2, D3);
596  MIB.addReg(D0);
597 
598  // Copy the other source register operand.
599  MIB.addOperand(MI.getOperand(OpIdx++));
600 
601  // Copy the predicate operands.
602  MIB.addOperand(MI.getOperand(OpIdx++));
603  MIB.addOperand(MI.getOperand(OpIdx++));
604 
605  if (SrcIsKill) // Add an implicit kill for the super-reg.
606  MIB->addRegisterKilled(SrcReg, TRI, true);
607  TransferImpOps(MI, MIB, MIB);
608  MI.eraseFromParent();
609 }
610 
611 void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB,
613  MachineInstr &MI = *MBBI;
614  unsigned Opcode = MI.getOpcode();
615  unsigned PredReg = 0;
616  ARMCC::CondCodes Pred = getInstrPredicate(&MI, PredReg);
617  unsigned DstReg = MI.getOperand(0).getReg();
618  bool DstIsDead = MI.getOperand(0).isDead();
619  bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm;
620  const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1);
621  MachineInstrBuilder LO16, HI16;
622 
623  if (!STI->hasV6T2Ops() &&
624  (Opcode == ARM::MOVi32imm || Opcode == ARM::MOVCCi32imm)) {
625  // Expand into a movi + orr.
626  LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi), DstReg);
627  HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ORRri))
628  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
629  .addReg(DstReg);
630 
631  assert (MO.isImm() && "MOVi32imm w/ non-immediate source operand!");
632  unsigned ImmVal = (unsigned)MO.getImm();
633  unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal);
634  unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal);
635  LO16 = LO16.addImm(SOImmValV1);
636  HI16 = HI16.addImm(SOImmValV2);
637  LO16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
638  HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
639  LO16.addImm(Pred).addReg(PredReg).addReg(0);
640  HI16.addImm(Pred).addReg(PredReg).addReg(0);
641  TransferImpOps(MI, LO16, HI16);
642  MI.eraseFromParent();
643  return;
644  }
645 
646  unsigned LO16Opc = 0;
647  unsigned HI16Opc = 0;
648  if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) {
649  LO16Opc = ARM::t2MOVi16;
650  HI16Opc = ARM::t2MOVTi16;
651  } else {
652  LO16Opc = ARM::MOVi16;
653  HI16Opc = ARM::MOVTi16;
654  }
655 
656  LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg);
657  HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc))
658  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
659  .addReg(DstReg);
660 
661  if (MO.isImm()) {
662  unsigned Imm = MO.getImm();
663  unsigned Lo16 = Imm & 0xffff;
664  unsigned Hi16 = (Imm >> 16) & 0xffff;
665  LO16 = LO16.addImm(Lo16);
666  HI16 = HI16.addImm(Hi16);
667  } else {
668  const GlobalValue *GV = MO.getGlobal();
669  unsigned TF = MO.getTargetFlags();
670  LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16);
671  HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16);
672  }
673 
674  LO16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
675  HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
676  LO16.addImm(Pred).addReg(PredReg);
677  HI16.addImm(Pred).addReg(PredReg);
678 
679  TransferImpOps(MI, LO16, HI16);
680  MI.eraseFromParent();
681 }
682 
683 bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB,
685  MachineInstr &MI = *MBBI;
686  unsigned Opcode = MI.getOpcode();
687  switch (Opcode) {
688  default:
689  return false;
690  case ARM::VMOVScc:
691  case ARM::VMOVDcc: {
692  unsigned newOpc = Opcode == ARM::VMOVScc ? ARM::VMOVS : ARM::VMOVD;
693  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(newOpc),
694  MI.getOperand(1).getReg())
695  .addOperand(MI.getOperand(2))
696  .addImm(MI.getOperand(3).getImm()) // 'pred'
697  .addOperand(MI.getOperand(4));
698 
699  MI.eraseFromParent();
700  return true;
701  }
702  case ARM::t2MOVCCr:
703  case ARM::MOVCCr: {
704  unsigned Opc = AFI->isThumbFunction() ? ARM::t2MOVr : ARM::MOVr;
705  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc),
706  MI.getOperand(1).getReg())
707  .addOperand(MI.getOperand(2))
708  .addImm(MI.getOperand(3).getImm()) // 'pred'
709  .addOperand(MI.getOperand(4))
710  .addReg(0); // 's' bit
711 
712  MI.eraseFromParent();
713  return true;
714  }
715  case ARM::MOVCCsi: {
716  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
717  (MI.getOperand(1).getReg()))
718  .addOperand(MI.getOperand(2))
719  .addImm(MI.getOperand(3).getImm())
720  .addImm(MI.getOperand(4).getImm()) // 'pred'
721  .addOperand(MI.getOperand(5))
722  .addReg(0); // 's' bit
723 
724  MI.eraseFromParent();
725  return true;
726  }
727  case ARM::MOVCCsr: {
728  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsr),
729  (MI.getOperand(1).getReg()))
730  .addOperand(MI.getOperand(2))
731  .addOperand(MI.getOperand(3))
732  .addImm(MI.getOperand(4).getImm())
733  .addImm(MI.getOperand(5).getImm()) // 'pred'
734  .addOperand(MI.getOperand(6))
735  .addReg(0); // 's' bit
736 
737  MI.eraseFromParent();
738  return true;
739  }
740  case ARM::t2MOVCCi16:
741  case ARM::MOVCCi16: {
742  unsigned NewOpc = AFI->isThumbFunction() ? ARM::t2MOVi16 : ARM::MOVi16;
743  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc),
744  MI.getOperand(1).getReg())
745  .addImm(MI.getOperand(2).getImm())
746  .addImm(MI.getOperand(3).getImm()) // 'pred'
747  .addOperand(MI.getOperand(4));
748  MI.eraseFromParent();
749  return true;
750  }
751  case ARM::t2MOVCCi:
752  case ARM::MOVCCi: {
753  unsigned Opc = AFI->isThumbFunction() ? ARM::t2MOVi : ARM::MOVi;
754  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc),
755  MI.getOperand(1).getReg())
756  .addImm(MI.getOperand(2).getImm())
757  .addImm(MI.getOperand(3).getImm()) // 'pred'
758  .addOperand(MI.getOperand(4))
759  .addReg(0); // 's' bit
760 
761  MI.eraseFromParent();
762  return true;
763  }
764  case ARM::t2MVNCCi:
765  case ARM::MVNCCi: {
766  unsigned Opc = AFI->isThumbFunction() ? ARM::t2MVNi : ARM::MVNi;
767  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc),
768  MI.getOperand(1).getReg())
769  .addImm(MI.getOperand(2).getImm())
770  .addImm(MI.getOperand(3).getImm()) // 'pred'
771  .addOperand(MI.getOperand(4))
772  .addReg(0); // 's' bit
773 
774  MI.eraseFromParent();
775  return true;
776  }
777  case ARM::t2MOVCClsl:
778  case ARM::t2MOVCClsr:
779  case ARM::t2MOVCCasr:
780  case ARM::t2MOVCCror: {
781  unsigned NewOpc;
782  switch (Opcode) {
783  case ARM::t2MOVCClsl: NewOpc = ARM::t2LSLri; break;
784  case ARM::t2MOVCClsr: NewOpc = ARM::t2LSRri; break;
785  case ARM::t2MOVCCasr: NewOpc = ARM::t2ASRri; break;
786  case ARM::t2MOVCCror: NewOpc = ARM::t2RORri; break;
787  default: llvm_unreachable("unexpeced conditional move");
788  }
789  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc),
790  MI.getOperand(1).getReg())
791  .addOperand(MI.getOperand(2))
792  .addImm(MI.getOperand(3).getImm())
793  .addImm(MI.getOperand(4).getImm()) // 'pred'
794  .addOperand(MI.getOperand(5))
795  .addReg(0); // 's' bit
796  MI.eraseFromParent();
797  return true;
798  }
799  case ARM::Int_eh_sjlj_dispatchsetup: {
800  MachineFunction &MF = *MI.getParent()->getParent();
801  const ARMBaseInstrInfo *AII =
802  static_cast<const ARMBaseInstrInfo*>(TII);
803  const ARMBaseRegisterInfo &RI = AII->getRegisterInfo();
804  // For functions using a base pointer, we rematerialize it (via the frame
805  // pointer) here since eh.sjlj.setjmp and eh.sjlj.longjmp don't do it
806  // for us. Otherwise, expand to nothing.
807  if (RI.hasBasePointer(MF)) {
808  int32_t NumBytes = AFI->getFramePtrSpillOffset();
809  unsigned FramePtr = RI.getFrameRegister(MF);
810  assert(MF.getTarget().getFrameLowering()->hasFP(MF) &&
811  "base pointer without frame pointer?");
812 
813  if (AFI->isThumb2Function()) {
814  emitT2RegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6,
815  FramePtr, -NumBytes, ARMCC::AL, 0, *TII);
816  } else if (AFI->isThumbFunction()) {
818  FramePtr, -NumBytes, *TII, RI);
819  } else {
821  FramePtr, -NumBytes, ARMCC::AL, 0,
822  *TII);
823  }
824  // If there's dynamic realignment, adjust for it.
825  if (RI.needsStackRealignment(MF)) {
826  MachineFrameInfo *MFI = MF.getFrameInfo();
827  unsigned MaxAlign = MFI->getMaxAlignment();
828  assert (!AFI->isThumb1OnlyFunction());
829  // Emit bic r6, r6, MaxAlign
830  unsigned bicOpc = AFI->isThumbFunction() ?
831  ARM::t2BICri : ARM::BICri;
833  TII->get(bicOpc), ARM::R6)
834  .addReg(ARM::R6, RegState::Kill)
835  .addImm(MaxAlign-1)));
836  }
837 
838  }
839  MI.eraseFromParent();
840  return true;
841  }
842 
843  case ARM::MOVsrl_flag:
844  case ARM::MOVsra_flag: {
845  // These are just fancy MOVs instructions.
846  AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi),
847  MI.getOperand(0).getReg())
848  .addOperand(MI.getOperand(1))
849  .addImm(ARM_AM::getSORegOpc((Opcode == ARM::MOVsrl_flag ?
851  1)))
852  .addReg(ARM::CPSR, RegState::Define);
853  MI.eraseFromParent();
854  return true;
855  }
856  case ARM::RRX: {
857  // This encodes as "MOVs Rd, Rm, rrx
858  MachineInstrBuilder MIB =
859  AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),TII->get(ARM::MOVsi),
860  MI.getOperand(0).getReg())
861  .addOperand(MI.getOperand(1))
862  .addImm(ARM_AM::getSORegOpc(ARM_AM::rrx, 0)))
863  .addReg(0);
864  TransferImpOps(MI, MIB, MIB);
865  MI.eraseFromParent();
866  return true;
867  }
868  case ARM::tTPsoft:
869  case ARM::TPsoft: {
870  MachineInstrBuilder MIB =
871  BuildMI(MBB, MBBI, MI.getDebugLoc(),
872  TII->get(Opcode == ARM::tTPsoft ? ARM::tBL : ARM::BL))
873  .addExternalSymbol("__aeabi_read_tp", 0);
874 
876  TransferImpOps(MI, MIB, MIB);
877  MI.eraseFromParent();
878  return true;
879  }
880  case ARM::tLDRpci_pic:
881  case ARM::t2LDRpci_pic: {
882  unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic)
883  ? ARM::tLDRpci : ARM::t2LDRpci;
884  unsigned DstReg = MI.getOperand(0).getReg();
885  bool DstIsDead = MI.getOperand(0).isDead();
886  MachineInstrBuilder MIB1 =
887  AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),
888  TII->get(NewLdOpc), DstReg)
889  .addOperand(MI.getOperand(1)));
890  MIB1->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
891  MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
892  TII->get(ARM::tPICADD))
893  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
894  .addReg(DstReg)
895  .addOperand(MI.getOperand(2));
896  TransferImpOps(MI, MIB1, MIB2);
897  MI.eraseFromParent();
898  return true;
899  }
900 
901  case ARM::MOV_ga_dyn:
902  case ARM::MOV_ga_pcrel:
903  case ARM::MOV_ga_pcrel_ldr:
904  case ARM::t2MOV_ga_dyn:
905  case ARM::t2MOV_ga_pcrel: {
906  // Expand into movw + movw. Also "add pc" / ldr [pc] in PIC mode.
907  unsigned LabelId = AFI->createPICLabelUId();
908  unsigned DstReg = MI.getOperand(0).getReg();
909  bool DstIsDead = MI.getOperand(0).isDead();
910  const MachineOperand &MO1 = MI.getOperand(1);
911  const GlobalValue *GV = MO1.getGlobal();
912  unsigned TF = MO1.getTargetFlags();
913  bool isARM = (Opcode != ARM::t2MOV_ga_pcrel && Opcode!=ARM::t2MOV_ga_dyn);
914  bool isPIC = (Opcode != ARM::MOV_ga_dyn && Opcode != ARM::t2MOV_ga_dyn);
915  unsigned LO16Opc = isARM ? ARM::MOVi16_ga_pcrel : ARM::t2MOVi16_ga_pcrel;
916  unsigned HI16Opc = isARM ? ARM::MOVTi16_ga_pcrel :ARM::t2MOVTi16_ga_pcrel;
917  unsigned LO16TF = isPIC
919  unsigned HI16TF = isPIC
921  unsigned PICAddOpc = isARM
922  ? (Opcode == ARM::MOV_ga_pcrel_ldr ? ARM::PICLDR : ARM::PICADD)
923  : ARM::tPICADD;
924  MachineInstrBuilder MIB1 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
925  TII->get(LO16Opc), DstReg)
926  .addGlobalAddress(GV, MO1.getOffset(), TF | LO16TF)
927  .addImm(LabelId);
928  MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
929  TII->get(HI16Opc), DstReg)
930  .addReg(DstReg)
931  .addGlobalAddress(GV, MO1.getOffset(), TF | HI16TF)
932  .addImm(LabelId);
933  if (!isPIC) {
934  TransferImpOps(MI, MIB1, MIB2);
935  MI.eraseFromParent();
936  return true;
937  }
938 
939  MachineInstrBuilder MIB3 = BuildMI(MBB, MBBI, MI.getDebugLoc(),
940  TII->get(PICAddOpc))
941  .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead))
942  .addReg(DstReg).addImm(LabelId);
943  if (isARM) {
944  AddDefaultPred(MIB3);
945  if (Opcode == ARM::MOV_ga_pcrel_ldr)
946  MIB3->setMemRefs(MI.memoperands_begin(), MI.memoperands_end());
947  }
948  TransferImpOps(MI, MIB1, MIB3);
949  MI.eraseFromParent();
950  return true;
951  }
952 
953  case ARM::MOVi32imm:
954  case ARM::MOVCCi32imm:
955  case ARM::t2MOVi32imm:
956  case ARM::t2MOVCCi32imm:
957  ExpandMOV32BitImm(MBB, MBBI);
958  return true;
959 
960  case ARM::SUBS_PC_LR: {
961  MachineInstrBuilder MIB =
962  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri), ARM::PC)
963  .addReg(ARM::LR)
964  .addOperand(MI.getOperand(0))
965  .addOperand(MI.getOperand(1))
966  .addOperand(MI.getOperand(2))
967  .addReg(ARM::CPSR, RegState::Undef);
968  TransferImpOps(MI, MIB, MIB);
969  MI.eraseFromParent();
970  return true;
971  }
972  case ARM::VLDMQIA: {
973  unsigned NewOpc = ARM::VLDMDIA;
974  MachineInstrBuilder MIB =
975  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
976  unsigned OpIdx = 0;
977 
978  // Grab the Q register destination.
979  bool DstIsDead = MI.getOperand(OpIdx).isDead();
980  unsigned DstReg = MI.getOperand(OpIdx++).getReg();
981 
982  // Copy the source register.
983  MIB.addOperand(MI.getOperand(OpIdx++));
984 
985  // Copy the predicate operands.
986  MIB.addOperand(MI.getOperand(OpIdx++));
987  MIB.addOperand(MI.getOperand(OpIdx++));
988 
989  // Add the destination operands (D subregs).
990  unsigned D0 = TRI->getSubReg(DstReg, ARM::dsub_0);
991  unsigned D1 = TRI->getSubReg(DstReg, ARM::dsub_1);
992  MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead))
993  .addReg(D1, RegState::Define | getDeadRegState(DstIsDead));
994 
995  // Add an implicit def for the super-register.
996  MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead));
997  TransferImpOps(MI, MIB, MIB);
999  MI.eraseFromParent();
1000  return true;
1001  }
1002 
1003  case ARM::VSTMQIA: {
1004  unsigned NewOpc = ARM::VSTMDIA;
1005  MachineInstrBuilder MIB =
1006  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
1007  unsigned OpIdx = 0;
1008 
1009  // Grab the Q register source.
1010  bool SrcIsKill = MI.getOperand(OpIdx).isKill();
1011  unsigned SrcReg = MI.getOperand(OpIdx++).getReg();
1012 
1013  // Copy the destination register.
1014  MIB.addOperand(MI.getOperand(OpIdx++));
1015 
1016  // Copy the predicate operands.
1017  MIB.addOperand(MI.getOperand(OpIdx++));
1018  MIB.addOperand(MI.getOperand(OpIdx++));
1019 
1020  // Add the source operands (D subregs).
1021  unsigned D0 = TRI->getSubReg(SrcReg, ARM::dsub_0);
1022  unsigned D1 = TRI->getSubReg(SrcReg, ARM::dsub_1);
1023  MIB.addReg(D0).addReg(D1);
1024 
1025  if (SrcIsKill) // Add an implicit kill for the Q register.
1026  MIB->addRegisterKilled(SrcReg, TRI, true);
1027 
1028  TransferImpOps(MI, MIB, MIB);
1030  MI.eraseFromParent();
1031  return true;
1032  }
1033  case ARM::VDUPfqf:
1034  case ARM::VDUPfdf:{
1035  unsigned NewOpc = Opcode == ARM::VDUPfqf ? ARM::VDUPLN32q :
1036  ARM::VDUPLN32d;
1037  MachineInstrBuilder MIB =
1038  BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc));
1039  unsigned OpIdx = 0;
1040  unsigned SrcReg = MI.getOperand(1).getReg();
1041  unsigned Lane = TRI->getEncodingValue(SrcReg) & 1;
1042  unsigned DReg = TRI->getMatchingSuperReg(SrcReg,
1043  Lane & 1 ? ARM::ssub_1 : ARM::ssub_0,
1044  &ARM::DPR_VFP2RegClass);
1045  // The lane is [0,1] for the containing DReg superregister.
1046  // Copy the dst/src register operands.
1047  MIB.addOperand(MI.getOperand(OpIdx++));
1048  MIB.addReg(DReg);
1049  ++OpIdx;
1050  // Add the lane select operand.
1051  MIB.addImm(Lane);
1052  // Add the predicate operands.
1053  MIB.addOperand(MI.getOperand(OpIdx++));
1054  MIB.addOperand(MI.getOperand(OpIdx++));
1055 
1056  TransferImpOps(MI, MIB, MIB);
1057  MI.eraseFromParent();
1058  return true;
1059  }
1060 
1061  case ARM::VLD2q8Pseudo:
1062  case ARM::VLD2q16Pseudo:
1063  case ARM::VLD2q32Pseudo:
1064  case ARM::VLD2q8PseudoWB_fixed:
1065  case ARM::VLD2q16PseudoWB_fixed:
1066  case ARM::VLD2q32PseudoWB_fixed:
1067  case ARM::VLD2q8PseudoWB_register:
1068  case ARM::VLD2q16PseudoWB_register:
1069  case ARM::VLD2q32PseudoWB_register:
1070  case ARM::VLD3d8Pseudo:
1071  case ARM::VLD3d16Pseudo:
1072  case ARM::VLD3d32Pseudo:
1073  case ARM::VLD1d64TPseudo:
1074  case ARM::VLD3d8Pseudo_UPD:
1075  case ARM::VLD3d16Pseudo_UPD:
1076  case ARM::VLD3d32Pseudo_UPD:
1077  case ARM::VLD3q8Pseudo_UPD:
1078  case ARM::VLD3q16Pseudo_UPD:
1079  case ARM::VLD3q32Pseudo_UPD:
1080  case ARM::VLD3q8oddPseudo:
1081  case ARM::VLD3q16oddPseudo:
1082  case ARM::VLD3q32oddPseudo:
1083  case ARM::VLD3q8oddPseudo_UPD:
1084  case ARM::VLD3q16oddPseudo_UPD:
1085  case ARM::VLD3q32oddPseudo_UPD:
1086  case ARM::VLD4d8Pseudo:
1087  case ARM::VLD4d16Pseudo:
1088  case ARM::VLD4d32Pseudo:
1089  case ARM::VLD1d64QPseudo:
1090  case ARM::VLD4d8Pseudo_UPD:
1091  case ARM::VLD4d16Pseudo_UPD:
1092  case ARM::VLD4d32Pseudo_UPD:
1093  case ARM::VLD4q8Pseudo_UPD:
1094  case ARM::VLD4q16Pseudo_UPD:
1095  case ARM::VLD4q32Pseudo_UPD:
1096  case ARM::VLD4q8oddPseudo:
1097  case ARM::VLD4q16oddPseudo:
1098  case ARM::VLD4q32oddPseudo:
1099  case ARM::VLD4q8oddPseudo_UPD:
1100  case ARM::VLD4q16oddPseudo_UPD:
1101  case ARM::VLD4q32oddPseudo_UPD:
1102  case ARM::VLD3DUPd8Pseudo:
1103  case ARM::VLD3DUPd16Pseudo:
1104  case ARM::VLD3DUPd32Pseudo:
1105  case ARM::VLD3DUPd8Pseudo_UPD:
1106  case ARM::VLD3DUPd16Pseudo_UPD:
1107  case ARM::VLD3DUPd32Pseudo_UPD:
1108  case ARM::VLD4DUPd8Pseudo:
1109  case ARM::VLD4DUPd16Pseudo:
1110  case ARM::VLD4DUPd32Pseudo:
1111  case ARM::VLD4DUPd8Pseudo_UPD:
1112  case ARM::VLD4DUPd16Pseudo_UPD:
1113  case ARM::VLD4DUPd32Pseudo_UPD:
1114  ExpandVLD(MBBI);
1115  return true;
1116 
1117  case ARM::VST2q8Pseudo:
1118  case ARM::VST2q16Pseudo:
1119  case ARM::VST2q32Pseudo:
1120  case ARM::VST2q8PseudoWB_fixed:
1121  case ARM::VST2q16PseudoWB_fixed:
1122  case ARM::VST2q32PseudoWB_fixed:
1123  case ARM::VST2q8PseudoWB_register:
1124  case ARM::VST2q16PseudoWB_register:
1125  case ARM::VST2q32PseudoWB_register:
1126  case ARM::VST3d8Pseudo:
1127  case ARM::VST3d16Pseudo:
1128  case ARM::VST3d32Pseudo:
1129  case ARM::VST1d64TPseudo:
1130  case ARM::VST3d8Pseudo_UPD:
1131  case ARM::VST3d16Pseudo_UPD:
1132  case ARM::VST3d32Pseudo_UPD:
1133  case ARM::VST1d64TPseudoWB_fixed:
1134  case ARM::VST1d64TPseudoWB_register:
1135  case ARM::VST3q8Pseudo_UPD:
1136  case ARM::VST3q16Pseudo_UPD:
1137  case ARM::VST3q32Pseudo_UPD:
1138  case ARM::VST3q8oddPseudo:
1139  case ARM::VST3q16oddPseudo:
1140  case ARM::VST3q32oddPseudo:
1141  case ARM::VST3q8oddPseudo_UPD:
1142  case ARM::VST3q16oddPseudo_UPD:
1143  case ARM::VST3q32oddPseudo_UPD:
1144  case ARM::VST4d8Pseudo:
1145  case ARM::VST4d16Pseudo:
1146  case ARM::VST4d32Pseudo:
1147  case ARM::VST1d64QPseudo:
1148  case ARM::VST4d8Pseudo_UPD:
1149  case ARM::VST4d16Pseudo_UPD:
1150  case ARM::VST4d32Pseudo_UPD:
1151  case ARM::VST1d64QPseudoWB_fixed:
1152  case ARM::VST1d64QPseudoWB_register:
1153  case ARM::VST4q8Pseudo_UPD:
1154  case ARM::VST4q16Pseudo_UPD:
1155  case ARM::VST4q32Pseudo_UPD:
1156  case ARM::VST4q8oddPseudo:
1157  case ARM::VST4q16oddPseudo:
1158  case ARM::VST4q32oddPseudo:
1159  case ARM::VST4q8oddPseudo_UPD:
1160  case ARM::VST4q16oddPseudo_UPD:
1161  case ARM::VST4q32oddPseudo_UPD:
1162  ExpandVST(MBBI);
1163  return true;
1164 
1165  case ARM::VLD1LNq8Pseudo:
1166  case ARM::VLD1LNq16Pseudo:
1167  case ARM::VLD1LNq32Pseudo:
1168  case ARM::VLD1LNq8Pseudo_UPD:
1169  case ARM::VLD1LNq16Pseudo_UPD:
1170  case ARM::VLD1LNq32Pseudo_UPD:
1171  case ARM::VLD2LNd8Pseudo:
1172  case ARM::VLD2LNd16Pseudo:
1173  case ARM::VLD2LNd32Pseudo:
1174  case ARM::VLD2LNq16Pseudo:
1175  case ARM::VLD2LNq32Pseudo:
1176  case ARM::VLD2LNd8Pseudo_UPD:
1177  case ARM::VLD2LNd16Pseudo_UPD:
1178  case ARM::VLD2LNd32Pseudo_UPD:
1179  case ARM::VLD2LNq16Pseudo_UPD:
1180  case ARM::VLD2LNq32Pseudo_UPD:
1181  case ARM::VLD3LNd8Pseudo:
1182  case ARM::VLD3LNd16Pseudo:
1183  case ARM::VLD3LNd32Pseudo:
1184  case ARM::VLD3LNq16Pseudo:
1185  case ARM::VLD3LNq32Pseudo:
1186  case ARM::VLD3LNd8Pseudo_UPD:
1187  case ARM::VLD3LNd16Pseudo_UPD:
1188  case ARM::VLD3LNd32Pseudo_UPD:
1189  case ARM::VLD3LNq16Pseudo_UPD:
1190  case ARM::VLD3LNq32Pseudo_UPD:
1191  case ARM::VLD4LNd8Pseudo:
1192  case ARM::VLD4LNd16Pseudo:
1193  case ARM::VLD4LNd32Pseudo:
1194  case ARM::VLD4LNq16Pseudo:
1195  case ARM::VLD4LNq32Pseudo:
1196  case ARM::VLD4LNd8Pseudo_UPD:
1197  case ARM::VLD4LNd16Pseudo_UPD:
1198  case ARM::VLD4LNd32Pseudo_UPD:
1199  case ARM::VLD4LNq16Pseudo_UPD:
1200  case ARM::VLD4LNq32Pseudo_UPD:
1201  case ARM::VST1LNq8Pseudo:
1202  case ARM::VST1LNq16Pseudo:
1203  case ARM::VST1LNq32Pseudo:
1204  case ARM::VST1LNq8Pseudo_UPD:
1205  case ARM::VST1LNq16Pseudo_UPD:
1206  case ARM::VST1LNq32Pseudo_UPD:
1207  case ARM::VST2LNd8Pseudo:
1208  case ARM::VST2LNd16Pseudo:
1209  case ARM::VST2LNd32Pseudo:
1210  case ARM::VST2LNq16Pseudo:
1211  case ARM::VST2LNq32Pseudo:
1212  case ARM::VST2LNd8Pseudo_UPD:
1213  case ARM::VST2LNd16Pseudo_UPD:
1214  case ARM::VST2LNd32Pseudo_UPD:
1215  case ARM::VST2LNq16Pseudo_UPD:
1216  case ARM::VST2LNq32Pseudo_UPD:
1217  case ARM::VST3LNd8Pseudo:
1218  case ARM::VST3LNd16Pseudo:
1219  case ARM::VST3LNd32Pseudo:
1220  case ARM::VST3LNq16Pseudo:
1221  case ARM::VST3LNq32Pseudo:
1222  case ARM::VST3LNd8Pseudo_UPD:
1223  case ARM::VST3LNd16Pseudo_UPD:
1224  case ARM::VST3LNd32Pseudo_UPD:
1225  case ARM::VST3LNq16Pseudo_UPD:
1226  case ARM::VST3LNq32Pseudo_UPD:
1227  case ARM::VST4LNd8Pseudo:
1228  case ARM::VST4LNd16Pseudo:
1229  case ARM::VST4LNd32Pseudo:
1230  case ARM::VST4LNq16Pseudo:
1231  case ARM::VST4LNq32Pseudo:
1232  case ARM::VST4LNd8Pseudo_UPD:
1233  case ARM::VST4LNd16Pseudo_UPD:
1234  case ARM::VST4LNd32Pseudo_UPD:
1235  case ARM::VST4LNq16Pseudo_UPD:
1236  case ARM::VST4LNq32Pseudo_UPD:
1237  ExpandLaneOp(MBBI);
1238  return true;
1239 
1240  case ARM::VTBL3Pseudo: ExpandVTBL(MBBI, ARM::VTBL3, false); return true;
1241  case ARM::VTBL4Pseudo: ExpandVTBL(MBBI, ARM::VTBL4, false); return true;
1242  case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true); return true;
1243  case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true); return true;
1244  }
1245 }
1246 
1247 bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) {
1248  bool Modified = false;
1249 
1250  MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end();
1251  while (MBBI != E) {
1253  Modified |= ExpandMI(MBB, MBBI);
1254  MBBI = NMBBI;
1255  }
1256 
1257  return Modified;
1258 }
1259 
1260 bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) {
1261  const TargetMachine &TM = MF.getTarget();
1262  TII = static_cast<const ARMBaseInstrInfo*>(TM.getInstrInfo());
1263  TRI = TM.getRegisterInfo();
1264  STI = &TM.getSubtarget<ARMSubtarget>();
1265  AFI = MF.getInfo<ARMFunctionInfo>();
1266 
1267  bool Modified = false;
1268  for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E;
1269  ++MFI)
1270  Modified |= ExpandMBB(*MFI);
1271  if (VerifyARMPseudo)
1272  MF.verify(this, "After expanding ARM pseudo instructions.");
1273  return Modified;
1274 }
1275 
1276 /// createARMExpandPseudoPass - returns an instance of the pseudo instruction
1277 /// expansion pass.
1279  return new ARMExpandPseudo();
1280 }
unsigned getFrameRegister(const MachineFunction &MF) const
const MachineFunction * getParent() const
const GlobalValue * getGlobal() const
void verify(Pass *p=NULL, const char *Banner=NULL) const
static cl::opt< bool > VerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden, cl::desc("Verify machine code after expanding ARM pseudos"))
static unsigned getSORegOpc(ShiftOpc ShOp, unsigned Imm)
static const NEONLdStTableEntry * LookupNEONLdSt(unsigned Opcode)
bool isDead() const
void emitT2RegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
FunctionPass * createARMExpandPseudoPass()
void operator<(const Optional< T > &X, const Optional< U > &Y)
Poison comparison between two Optional objects. Clients needs to explicitly compare the underlying va...
const MCInstrDesc & getDesc() const
Definition: MachineInstr.h:257
unsigned getMaxAlignment() const
static const MachineInstrBuilder & AddDefaultPred(const MachineInstrBuilder &MIB)
static const NEONLdStTableEntry NEONLdStTable[]
const HexagonInstrInfo * TII
bool isImm() const
isImm - Tests if this is a MO_Immediate operand.
virtual bool hasFP(const MachineFunction &MF) const =0
#define llvm_unreachable(msg)
bool isReg() const
isReg - Tests if this is a MO_Register operand.
void setImplicit(bool Val=true)
Abstract Stack Frame Information.
bool isUndef() const
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
const MachineInstrBuilder & addImm(int64_t Val) const
unsigned getNumOperands() const
Definition: MachineInstr.h:265
bool isKill() const
size_t array_lengthof(T(&)[N])
Find the length of an array.
Definition: STLExtras.h:250
int getOpcode() const
Definition: MachineInstr.h:261
int64_t getImm() const
unsigned getUndefRegState(bool B)
unsigned getKillRegState(bool B)
const MachineBasicBlock * getParent() const
Definition: MachineInstr.h:119
unsigned getDeadRegState(bool B)
mmo_iterator memoperands_end() const
Definition: MachineInstr.h:292
bundle_iterator< MachineInstr, instr_iterator > iterator
unsigned getTargetFlags() const
const MachineInstrBuilder & setMemRefs(MachineInstr::mmo_iterator b, MachineInstr::mmo_iterator e) const
ARMCC::CondCodes getInstrPredicate(const MachineInstr *MI, unsigned &PredReg)
static unsigned getSOImmTwoPartSecond(unsigned V)
const MachineOperand & getOperand(unsigned i) const
Definition: MachineInstr.h:267
unsigned getSubReg(unsigned Reg, unsigned Idx) const
Returns the physical register number of sub-register "Index" for physical register RegNo...
ItTy next(ItTy it, Dist n)
Definition: STLExtras.h:154
void emitThumbRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, const TargetInstrInfo &TII, const ARMBaseRegisterInfo &MRI, unsigned MIFlags=0)
#define LLVM_ATTRIBUTE_UNUSED
Definition: Compiler.h:199
int64_t getOffset() const
MachineInstrBuilder BuildMI(MachineFunction &MF, DebugLoc DL, const MCInstrDesc &MCID)
virtual const TargetFrameLowering * getFrameLowering() const
void emitARMRegPlusImmediate(MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI, DebugLoc dl, unsigned DestReg, unsigned BaseReg, int NumBytes, ARMCC::CondCodes Pred, unsigned PredReg, const ARMBaseInstrInfo &TII, unsigned MIFlags=0)
bool needsStackRealignment(const MachineFunction &MF) const
virtual const TargetInstrInfo * getInstrInfo() const
static const MachineInstrBuilder & AddDefaultCC(const MachineInstrBuilder &MIB)
const STC & getSubtarget() const
#define R6(n)
MachineFrameInfo * getFrameInfo()
bool hasBasePointer(const MachineFunction &MF) const
const MachineInstrBuilder & addGlobalAddress(const GlobalValue *GV, int64_t Offset=0, unsigned char TargetFlags=0) const
static void GetDSubRegs(unsigned Reg, NEONRegSpacing RegSpc, const TargetRegisterInfo *TRI, unsigned &D0, unsigned &D1, unsigned &D2, unsigned &D3)
#define I(x, y, z)
Definition: MD5.cpp:54
const TargetMachine & getTarget() const
virtual const TargetRegisterInfo * getRegisterInfo() const
unsigned getReg() const
getReg - Returns the register number.
virtual const ARMBaseRegisterInfo & getRegisterInfo() const =0
unsigned getNumOperands() const
Return the number of declared MachineOperands for this MachineInstruction. Note that variadic (isVari...
Definition: MCInstrDesc.h:190
const MachineInstrBuilder & addOperand(const MachineOperand &MO) const
BasicBlockListType::iterator iterator
bool addRegisterKilled(unsigned IncomingReg, const TargetRegisterInfo *RegInfo, bool AddIfNotFound=false)
static unsigned getSOImmTwoPartFirst(unsigned V)
const MachineInstrBuilder & addReg(unsigned RegNo, unsigned flags=0, unsigned SubReg=0) const
void setMemRefs(mmo_iterator NewMemRefs, mmo_iterator NewMemRefsEnd)
DebugLoc getDebugLoc() const
Definition: MachineInstr.h:244
mmo_iterator memoperands_begin() const
Access to memory operands of the instruction.
Definition: MachineInstr.h:291