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