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