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