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