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