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