ARMExpandPseudoInsts.cpp revision 263508
11539Srgrimes//===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -------------===// 21539Srgrimes// 31539Srgrimes// The LLVM Compiler Infrastructure 41539Srgrimes// 51539Srgrimes// This file is distributed under the University of Illinois Open Source 61539Srgrimes// License. See LICENSE.TXT for details. 71539Srgrimes// 81539Srgrimes//===----------------------------------------------------------------------===// 91539Srgrimes// 101539Srgrimes// This file contains a pass that expands pseudo instructions into target 111539Srgrimes// instructions to allow proper scheduling, if-conversion, and other late 121539Srgrimes// optimizations. This pass should be run after register allocation but before 13203964Simp// the post-regalloc scheduling pass. 141539Srgrimes// 151539Srgrimes//===----------------------------------------------------------------------===// 161539Srgrimes 171539Srgrimes#define DEBUG_TYPE "arm-pseudo" 181539Srgrimes#include "ARM.h" 191539Srgrimes#include "ARMBaseInstrInfo.h" 201539Srgrimes#include "ARMBaseRegisterInfo.h" 211539Srgrimes#include "ARMMachineFunctionInfo.h" 221539Srgrimes#include "MCTargetDesc/ARMAddressingModes.h" 231539Srgrimes#include "llvm/CodeGen/MachineFrameInfo.h" 241539Srgrimes#include "llvm/CodeGen/MachineFunctionPass.h" 251539Srgrimes#include "llvm/CodeGen/MachineInstrBuilder.h" 261539Srgrimes#include "llvm/Support/CommandLine.h" 271539Srgrimes#include "llvm/Support/raw_ostream.h" // FIXME: for debug only. remove! 281539Srgrimes#include "llvm/Target/TargetFrameLowering.h" 2923657Speter#include "llvm/Target/TargetRegisterInfo.h" 3055031Sbdeusing namespace llvm; 311539Srgrimes 321539Srgrimesstatic cl::opt<bool> 331539SrgrimesVerifyARMPseudo("verify-arm-pseudo-expand", cl::Hidden, 347865Sbde cl::desc("Verify machine code after expanding ARM pseudos")); 351539Srgrimes 3633861Sbdenamespace { 37123257Smarcel class ARMExpandPseudo : public MachineFunctionPass { 38102227Smike public: 3933861Sbde static char ID; 40103728Swollman ARMExpandPseudo() : MachineFunctionPass(ID) {} 41102227Smike 42102227Smike const ARMBaseInstrInfo *TII; 43102227Smike const TargetRegisterInfo *TRI; 4415483Sbde const ARMSubtarget *STI; 4515483Sbde ARMFunctionInfo *AFI; 4615483Sbde 47102227Smike virtual bool runOnMachineFunction(MachineFunction &Fn); 48102227Smike 49102227Smike virtual const char *getPassName() const { 501539Srgrimes return "ARM pseudo instruction expansion pass"; 511539Srgrimes } 5299640Sobrien 53102227Smike private: 54102227Smike void TransferImpOps(MachineInstr &OldMI, 55102227Smike MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI); 561539Srgrimes bool ExpandMI(MachineBasicBlock &MBB, 5799640Sobrien MachineBasicBlock::iterator MBBI); 581539Srgrimes bool ExpandMBB(MachineBasicBlock &MBB); 591539Srgrimes void ExpandVLD(MachineBasicBlock::iterator &MBBI); 60103766Sbde void ExpandVST(MachineBasicBlock::iterator &MBBI); 61103766Sbde void ExpandLaneOp(MachineBasicBlock::iterator &MBBI); 621539Srgrimes void ExpandVTBL(MachineBasicBlock::iterator &MBBI, 631539Srgrimes unsigned Opc, bool IsExt); 641539Srgrimes void ExpandMOV32BitImm(MachineBasicBlock &MBB, 65103766Sbde MachineBasicBlock::iterator &MBBI); 66103766Sbde }; 671539Srgrimes char ARMExpandPseudo::ID = 0; 681539Srgrimes} 691539Srgrimes 701539Srgrimes/// TransferImpOps - Transfer implicit operands on the pseudo instruction to 711539Srgrimes/// the instructions created from the expansion. 721539Srgrimesvoid ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI, 731539Srgrimes MachineInstrBuilder &UseMI, 74227753Stheraven MachineInstrBuilder &DefMI) { 75233600Stheraven const MCInstrDesc &Desc = OldMI.getDesc(); 76233600Stheraven for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands(); 77233600Stheraven i != e; ++i) { 781539Srgrimes const MachineOperand &MO = OldMI.getOperand(i); 79227753Stheraven assert(MO.isReg() && MO.getReg()); 80227753Stheraven if (MO.isUse()) 811539Srgrimes UseMI.addOperand(MO); 82228330Stheraven else 8393032Simp DefMI.addOperand(MO); 8493032Simp } 8593032Simp} 8693032Simp 8793032Simpnamespace { 8893032Simp // Constants for register spacing in NEON load/store instructions. 8993032Simp // For quad-register load-lane and store-lane pseudo instructors, the 90187961Sdas // spacing is initially assumed to be EvenDblSpc, and that is changed to 9193032Simp // OddDblSpc depending on the lane number operand. 92228330Stheraven enum NEONRegSpacing { 9393032Simp SingleSpc, 9493032Simp EvenDblSpc, 9593032Simp OddDblSpc 9693032Simp }; 97187961Sdas 98103728Swollman // Entries for NEON load/store information table. The table is sorted by 99103766Sbde // PseudoOpc for fast binary-search lookups. 100103728Swollman struct NEONLdStTableEntry { 10193032Simp uint16_t PseudoOpc; 10293032Simp uint16_t RealOpc; 10393032Simp bool IsLoad; 10493032Simp bool isUpdating; 10593032Simp bool hasWritebackOperand; 106103766Sbde uint8_t RegSpacing; // One of type NEONRegSpacing 107112163Sdas uint8_t NumRegs; // D registers loaded or stored 108103766Sbde uint8_t RegElts; // elements per D register; used for lane ops 109112163Sdas // FIXME: Temporary flag to denote whether the real instruction takes 110112163Sdas // a single register (like the encoding) or all of the registers in 1111539Srgrimes // the list (like the asm syntax and the isel DAG). When all definitions 112103012Stjr // are converted to take only the single encoded register, this will 11393032Simp // go away. 11493032Simp bool copyAllListRegs; 115103012Stjr 1161539Srgrimes // Comparison methods for binary search of the table. 117103728Swollman bool operator<(const NEONLdStTableEntry &TE) const { 118103728Swollman return PseudoOpc < TE.PseudoOpc; 119103728Swollman } 120103728Swollman friend bool operator<(const NEONLdStTableEntry &TE, unsigned PseudoOpc) { 121103728Swollman return TE.PseudoOpc < PseudoOpc; 122103728Swollman } 123103728Swollman friend bool LLVM_ATTRIBUTE_UNUSED operator<(unsigned PseudoOpc, 124103728Swollman const NEONLdStTableEntry &TE) { 125103728Swollman return PseudoOpc < TE.PseudoOpc; 126103728Swollman } 127103728Swollman }; 128103728Swollman} 129103728Swollman 130103728Swollmanstatic const NEONLdStTableEntry NEONLdStTable[] = { 131103728Swollman{ ARM::VLD1LNq16Pseudo, ARM::VLD1LNd16, true, false, false, EvenDblSpc, 1, 4 ,true}, 132103728Swollman{ ARM::VLD1LNq16Pseudo_UPD, ARM::VLD1LNd16_UPD, true, true, true, EvenDblSpc, 1, 4 ,true}, 133103728Swollman{ ARM::VLD1LNq32Pseudo, ARM::VLD1LNd32, true, false, false, EvenDblSpc, 1, 2 ,true}, 13469201Sphk{ ARM::VLD1LNq32Pseudo_UPD, ARM::VLD1LNd32_UPD, true, true, true, EvenDblSpc, 1, 2 ,true}, 135103728Swollman{ ARM::VLD1LNq8Pseudo, ARM::VLD1LNd8, true, false, false, EvenDblSpc, 1, 8 ,true}, 136103728Swollman{ ARM::VLD1LNq8Pseudo_UPD, ARM::VLD1LNd8_UPD, true, true, true, EvenDblSpc, 1, 8 ,true}, 137103728Swollman 138103728Swollman{ ARM::VLD1d64QPseudo, ARM::VLD1d64Q, true, false, false, SingleSpc, 4, 1 ,false}, 139103728Swollman{ ARM::VLD1d64TPseudo, ARM::VLD1d64T, true, false, false, SingleSpc, 3, 1 ,false}, 140103728Swollman 141103728Swollman{ ARM::VLD2LNd16Pseudo, ARM::VLD2LNd16, true, false, false, SingleSpc, 2, 4 ,true}, 142103728Swollman{ ARM::VLD2LNd16Pseudo_UPD, ARM::VLD2LNd16_UPD, true, true, true, SingleSpc, 2, 4 ,true}, 143103728Swollman{ ARM::VLD2LNd32Pseudo, ARM::VLD2LNd32, true, false, false, SingleSpc, 2, 2 ,true}, 144103766Sbde{ ARM::VLD2LNd32Pseudo_UPD, ARM::VLD2LNd32_UPD, true, true, true, SingleSpc, 2, 2 ,true}, 145103766Sbde{ ARM::VLD2LNd8Pseudo, ARM::VLD2LNd8, true, false, false, SingleSpc, 2, 8 ,true}, 146103728Swollman{ ARM::VLD2LNd8Pseudo_UPD, ARM::VLD2LNd8_UPD, true, true, true, SingleSpc, 2, 8 ,true}, 147103728Swollman{ ARM::VLD2LNq16Pseudo, ARM::VLD2LNq16, true, false, false, EvenDblSpc, 2, 4 ,true}, 148103766Sbde{ ARM::VLD2LNq16Pseudo_UPD, ARM::VLD2LNq16_UPD, true, true, true, EvenDblSpc, 2, 4 ,true}, 149103728Swollman{ ARM::VLD2LNq32Pseudo, ARM::VLD2LNq32, true, false, false, EvenDblSpc, 2, 2 ,true}, 150103728Swollman{ ARM::VLD2LNq32Pseudo_UPD, ARM::VLD2LNq32_UPD, true, true, true, EvenDblSpc, 2, 2 ,true}, 151228330Stheraven 152103728Swollman{ ARM::VLD2q16Pseudo, ARM::VLD2q16, true, false, false, SingleSpc, 4, 4 ,false}, 153103728Swollman{ ARM::VLD2q16PseudoWB_fixed, ARM::VLD2q16wb_fixed, true, true, false, SingleSpc, 4, 4 ,false}, 154103728Swollman{ ARM::VLD2q16PseudoWB_register, ARM::VLD2q16wb_register, true, true, true, SingleSpc, 4, 4 ,false}, 155229807Sed{ ARM::VLD2q32Pseudo, ARM::VLD2q32, true, false, false, SingleSpc, 4, 2 ,false}, 156228322Stheraven{ ARM::VLD2q32PseudoWB_fixed, ARM::VLD2q32wb_fixed, true, true, false, SingleSpc, 4, 2 ,false}, 157232971Stheraven{ ARM::VLD2q32PseudoWB_register, ARM::VLD2q32wb_register, true, true, true, SingleSpc, 4, 2 ,false}, 158234370Sjasone{ ARM::VLD2q8Pseudo, ARM::VLD2q8, true, false, false, SingleSpc, 4, 8 ,false}, 159229807Sed{ ARM::VLD2q8PseudoWB_fixed, ARM::VLD2q8wb_fixed, true, true, false, SingleSpc, 4, 8 ,false}, 160228901Sed{ ARM::VLD2q8PseudoWB_register, ARM::VLD2q8wb_register, true, true, true, SingleSpc, 4, 8 ,false}, 161228901Sed 162228901Sed{ ARM::VLD3DUPd16Pseudo, ARM::VLD3DUPd16, true, false, false, SingleSpc, 3, 4,true}, 163228322Stheraven{ ARM::VLD3DUPd16Pseudo_UPD, ARM::VLD3DUPd16_UPD, true, true, true, SingleSpc, 3, 4,true}, 164103728Swollman{ ARM::VLD3DUPd32Pseudo, ARM::VLD3DUPd32, true, false, false, SingleSpc, 3, 2,true}, 165103728Swollman{ ARM::VLD3DUPd32Pseudo_UPD, ARM::VLD3DUPd32_UPD, true, true, true, SingleSpc, 3, 2,true}, 166103728Swollman{ ARM::VLD3DUPd8Pseudo, ARM::VLD3DUPd8, true, false, false, SingleSpc, 3, 8,true}, 167103728Swollman{ ARM::VLD3DUPd8Pseudo_UPD, ARM::VLD3DUPd8_UPD, true, true, true, SingleSpc, 3, 8,true}, 168103728Swollman 169154250Sjasone{ ARM::VLD3LNd16Pseudo, ARM::VLD3LNd16, true, false, false, SingleSpc, 3, 4 ,true}, 170103728Swollman{ ARM::VLD3LNd16Pseudo_UPD, ARM::VLD3LNd16_UPD, true, true, true, SingleSpc, 3, 4 ,true}, 171206997Skib{ ARM::VLD3LNd32Pseudo, ARM::VLD3LNd32, true, false, false, SingleSpc, 3, 2 ,true}, 17293032Simp{ ARM::VLD3LNd32Pseudo_UPD, ARM::VLD3LNd32_UPD, true, true, true, SingleSpc, 3, 2 ,true}, 173171195Sscf{ ARM::VLD3LNd8Pseudo, ARM::VLD3LNd8, true, false, false, SingleSpc, 3, 8 ,true}, 174103728Swollman{ ARM::VLD3LNd8Pseudo_UPD, ARM::VLD3LNd8_UPD, true, true, true, SingleSpc, 3, 8 ,true}, 1751539Srgrimes{ ARM::VLD3LNq16Pseudo, ARM::VLD3LNq16, true, false, false, EvenDblSpc, 3, 4 ,true}, 176189349Sdas{ ARM::VLD3LNq16Pseudo_UPD, ARM::VLD3LNq16_UPD, true, true, true, EvenDblSpc, 3, 4 ,true}, 177189349Sdas{ ARM::VLD3LNq32Pseudo, ARM::VLD3LNq32, true, false, false, EvenDblSpc, 3, 2 ,true}, 178189349Sdas{ ARM::VLD3LNq32Pseudo_UPD, ARM::VLD3LNq32_UPD, true, true, true, EvenDblSpc, 3, 2 ,true}, 179189349Sdas 180189349Sdas{ ARM::VLD3d16Pseudo, ARM::VLD3d16, true, false, false, SingleSpc, 3, 4 ,true}, 181189349Sdas{ ARM::VLD3d16Pseudo_UPD, ARM::VLD3d16_UPD, true, true, true, SingleSpc, 3, 4 ,true}, 182189349Sdas{ ARM::VLD3d32Pseudo, ARM::VLD3d32, true, false, false, SingleSpc, 3, 2 ,true}, 183189349Sdas{ ARM::VLD3d32Pseudo_UPD, ARM::VLD3d32_UPD, true, true, true, SingleSpc, 3, 2 ,true}, 184189349Sdas{ ARM::VLD3d8Pseudo, ARM::VLD3d8, true, false, false, SingleSpc, 3, 8 ,true}, 185189349Sdas{ ARM::VLD3d8Pseudo_UPD, ARM::VLD3d8_UPD, true, true, true, SingleSpc, 3, 8 ,true}, 186189349Sdas 187189349Sdas{ ARM::VLD3q16Pseudo_UPD, ARM::VLD3q16_UPD, true, true, true, EvenDblSpc, 3, 4 ,true}, 188103728Swollman{ ARM::VLD3q16oddPseudo, ARM::VLD3q16, true, false, false, OddDblSpc, 3, 4 ,true}, 189103728Swollman{ ARM::VLD3q16oddPseudo_UPD, ARM::VLD3q16_UPD, true, true, true, OddDblSpc, 3, 4 ,true}, 190103728Swollman{ ARM::VLD3q32Pseudo_UPD, ARM::VLD3q32_UPD, true, true, true, EvenDblSpc, 3, 2 ,true}, 191103728Swollman{ ARM::VLD3q32oddPseudo, ARM::VLD3q32, true, false, false, OddDblSpc, 3, 2 ,true}, 192103728Swollman{ ARM::VLD3q32oddPseudo_UPD, ARM::VLD3q32_UPD, true, true, true, OddDblSpc, 3, 2 ,true}, 193103728Swollman{ ARM::VLD3q8Pseudo_UPD, ARM::VLD3q8_UPD, true, true, true, EvenDblSpc, 3, 8 ,true}, 194103728Swollman{ ARM::VLD3q8oddPseudo, ARM::VLD3q8, true, false, false, OddDblSpc, 3, 8 ,true}, 195103728Swollman{ ARM::VLD3q8oddPseudo_UPD, ARM::VLD3q8_UPD, true, true, true, OddDblSpc, 3, 8 ,true}, 196153707Strhodes 19793032Simp{ ARM::VLD4DUPd16Pseudo, ARM::VLD4DUPd16, true, false, false, SingleSpc, 4, 4,true}, 198103766Sbde{ ARM::VLD4DUPd16Pseudo_UPD, ARM::VLD4DUPd16_UPD, true, true, true, SingleSpc, 4, 4,true}, 19993032Simp{ ARM::VLD4DUPd32Pseudo, ARM::VLD4DUPd32, true, false, false, SingleSpc, 4, 2,true}, 200103766Sbde{ ARM::VLD4DUPd32Pseudo_UPD, ARM::VLD4DUPd32_UPD, true, true, true, SingleSpc, 4, 2,true}, 201103766Sbde{ ARM::VLD4DUPd8Pseudo, ARM::VLD4DUPd8, true, false, false, SingleSpc, 4, 8,true}, 202108574Sjmallett{ ARM::VLD4DUPd8Pseudo_UPD, ARM::VLD4DUPd8_UPD, true, true, true, SingleSpc, 4, 8,true}, 203103728Swollman 20493032Simp{ ARM::VLD4LNd16Pseudo, ARM::VLD4LNd16, true, false, false, SingleSpc, 4, 4 ,true}, 205153707Strhodes{ ARM::VLD4LNd16Pseudo_UPD, ARM::VLD4LNd16_UPD, true, true, true, SingleSpc, 4, 4 ,true}, 20693032Simp{ ARM::VLD4LNd32Pseudo, ARM::VLD4LNd32, true, false, false, SingleSpc, 4, 2 ,true}, 20793032Simp{ ARM::VLD4LNd32Pseudo_UPD, ARM::VLD4LNd32_UPD, true, true, true, SingleSpc, 4, 2 ,true}, 208189782Sdas{ ARM::VLD4LNd8Pseudo, ARM::VLD4LNd8, true, false, false, SingleSpc, 4, 8 ,true}, 209103728Swollman{ ARM::VLD4LNd8Pseudo_UPD, ARM::VLD4LNd8_UPD, true, true, true, SingleSpc, 4, 8 ,true}, 210103766Sbde{ ARM::VLD4LNq16Pseudo, ARM::VLD4LNq16, true, false, false, EvenDblSpc, 4, 4 ,true}, 211103728Swollman{ ARM::VLD4LNq16Pseudo_UPD, ARM::VLD4LNq16_UPD, true, true, true, EvenDblSpc, 4, 4 ,true}, 21293032Simp{ ARM::VLD4LNq32Pseudo, ARM::VLD4LNq32, true, false, false, EvenDblSpc, 4, 2 ,true}, 21393032Simp{ ARM::VLD4LNq32Pseudo_UPD, ARM::VLD4LNq32_UPD, true, true, true, EvenDblSpc, 4, 2 ,true}, 214108574Sjmallett 215108574Sjmallett{ ARM::VLD4d16Pseudo, ARM::VLD4d16, true, false, false, SingleSpc, 4, 4 ,true}, 216171195Sscf{ ARM::VLD4d16Pseudo_UPD, ARM::VLD4d16_UPD, true, true, true, SingleSpc, 4, 4 ,true}, 217103728Swollman{ ARM::VLD4d32Pseudo, ARM::VLD4d32, true, false, false, SingleSpc, 4, 2 ,true}, 2187865Sbde{ ARM::VLD4d32Pseudo_UPD, ARM::VLD4d32_UPD, true, true, true, SingleSpc, 4, 2 ,true}, 21993032Simp{ ARM::VLD4d8Pseudo, ARM::VLD4d8, true, false, false, SingleSpc, 4, 8 ,true}, 220103728Swollman{ ARM::VLD4d8Pseudo_UPD, ARM::VLD4d8_UPD, true, true, true, SingleSpc, 4, 8 ,true}, 221103728Swollman 222103728Swollman{ ARM::VLD4q16Pseudo_UPD, ARM::VLD4q16_UPD, true, true, true, EvenDblSpc, 4, 4 ,true}, 223103728Swollman{ ARM::VLD4q16oddPseudo, ARM::VLD4q16, true, false, false, OddDblSpc, 4, 4 ,true}, 224103728Swollman{ ARM::VLD4q16oddPseudo_UPD, ARM::VLD4q16_UPD, true, true, true, OddDblSpc, 4, 4 ,true}, 22593032Simp{ ARM::VLD4q32Pseudo_UPD, ARM::VLD4q32_UPD, true, true, true, EvenDblSpc, 4, 2 ,true}, 226103728Swollman{ ARM::VLD4q32oddPseudo, ARM::VLD4q32, true, false, false, OddDblSpc, 4, 2 ,true}, 227108574Sjmallett{ ARM::VLD4q32oddPseudo_UPD, ARM::VLD4q32_UPD, true, true, true, OddDblSpc, 4, 2 ,true}, 228103728Swollman{ ARM::VLD4q8Pseudo_UPD, ARM::VLD4q8_UPD, true, true, true, EvenDblSpc, 4, 8 ,true}, 2294749Sats{ ARM::VLD4q8oddPseudo, ARM::VLD4q8, true, false, false, OddDblSpc, 4, 8 ,true}, 230103728Swollman{ ARM::VLD4q8oddPseudo_UPD, ARM::VLD4q8_UPD, true, true, true, OddDblSpc, 4, 8 ,true}, 231234370Sjasone 232234370Sjasone{ ARM::VST1LNq16Pseudo, ARM::VST1LNd16, false, false, false, EvenDblSpc, 1, 4 ,true}, 233103728Swollman{ ARM::VST1LNq16Pseudo_UPD, ARM::VST1LNd16_UPD, false, true, true, EvenDblSpc, 1, 4 ,true}, 234116397Sdes{ ARM::VST1LNq32Pseudo, ARM::VST1LNd32, false, false, false, EvenDblSpc, 1, 2 ,true}, 235116397Sdes{ ARM::VST1LNq32Pseudo_UPD, ARM::VST1LNd32_UPD, false, true, true, EvenDblSpc, 1, 2 ,true}, 236116397Sdes{ ARM::VST1LNq8Pseudo, ARM::VST1LNd8, false, false, false, EvenDblSpc, 1, 8 ,true}, 237116397Sdes{ ARM::VST1LNq8Pseudo_UPD, ARM::VST1LNd8_UPD, false, true, true, EvenDblSpc, 1, 8 ,true}, 238116397Sdes 239116397Sdes{ ARM::VST1d64QPseudo, ARM::VST1d64Q, false, false, false, SingleSpc, 4, 1 ,false}, 240116397Sdes{ ARM::VST1d64QPseudoWB_fixed, ARM::VST1d64Qwb_fixed, false, true, false, SingleSpc, 4, 1 ,false}, 241116397Sdes{ ARM::VST1d64QPseudoWB_register, ARM::VST1d64Qwb_register, false, true, true, SingleSpc, 4, 1 ,false}, 242116397Sdes{ ARM::VST1d64TPseudo, ARM::VST1d64T, false, false, false, SingleSpc, 3, 1 ,false}, 243116831Sobrien{ ARM::VST1d64TPseudoWB_fixed, ARM::VST1d64Twb_fixed, false, true, false, SingleSpc, 3, 1 ,false}, 244116831Sobrien{ ARM::VST1d64TPseudoWB_register, ARM::VST1d64Twb_register, false, true, true, SingleSpc, 3, 1 ,false}, 245116397Sdes 246116831Sobrien{ ARM::VST2LNd16Pseudo, ARM::VST2LNd16, false, false, false, SingleSpc, 2, 4 ,true}, 247116831Sobrien{ ARM::VST2LNd16Pseudo_UPD, ARM::VST2LNd16_UPD, false, true, true, SingleSpc, 2, 4 ,true}, 248116397Sdes{ ARM::VST2LNd32Pseudo, ARM::VST2LNd32, false, false, false, SingleSpc, 2, 2 ,true}, 249116397Sdes{ ARM::VST2LNd32Pseudo_UPD, ARM::VST2LNd32_UPD, false, true, true, SingleSpc, 2, 2 ,true}, 250189820Sdas{ ARM::VST2LNd8Pseudo, ARM::VST2LNd8, false, false, false, SingleSpc, 2, 8 ,true}, 25141927Sdt{ ARM::VST2LNd8Pseudo_UPD, ARM::VST2LNd8_UPD, false, true, true, SingleSpc, 2, 8 ,true}, 25293032Simp{ ARM::VST2LNq16Pseudo, ARM::VST2LNq16, false, false, false, EvenDblSpc, 2, 4,true}, 253180658Sache{ ARM::VST2LNq16Pseudo_UPD, ARM::VST2LNq16_UPD, false, true, true, EvenDblSpc, 2, 4,true}, 254180658Sache{ ARM::VST2LNq32Pseudo, ARM::VST2LNq32, false, false, false, EvenDblSpc, 2, 2,true}, 25593032Simp{ ARM::VST2LNq32Pseudo_UPD, ARM::VST2LNq32_UPD, false, true, true, EvenDblSpc, 2, 2,true}, 256180689Sache 257180689Sache{ ARM::VST2q16Pseudo, ARM::VST2q16, false, false, false, SingleSpc, 4, 4 ,false}, 258108445Sobrien{ ARM::VST2q16PseudoWB_fixed, ARM::VST2q16wb_fixed, false, true, false, SingleSpc, 4, 4 ,false}, 259103728Swollman{ ARM::VST2q16PseudoWB_register, ARM::VST2q16wb_register, false, true, true, SingleSpc, 4, 4 ,false}, 26093032Simp{ ARM::VST2q32Pseudo, ARM::VST2q32, false, false, false, SingleSpc, 4, 2 ,false}, 26193032Simp{ ARM::VST2q32PseudoWB_fixed, ARM::VST2q32wb_fixed, false, true, false, SingleSpc, 4, 2 ,false}, 26293032Simp{ ARM::VST2q32PseudoWB_register, ARM::VST2q32wb_register, false, true, true, SingleSpc, 4, 2 ,false}, 26393032Simp{ ARM::VST2q8Pseudo, ARM::VST2q8, false, false, false, SingleSpc, 4, 8 ,false}, 26493032Simp{ ARM::VST2q8PseudoWB_fixed, ARM::VST2q8wb_fixed, false, true, false, SingleSpc, 4, 8 ,false}, 26593032Simp{ ARM::VST2q8PseudoWB_register, ARM::VST2q8wb_register, false, true, true, SingleSpc, 4, 8 ,false}, 26693032Simp 26793032Simp{ ARM::VST3LNd16Pseudo, ARM::VST3LNd16, false, false, false, SingleSpc, 3, 4 ,true}, 26893032Simp{ ARM::VST3LNd16Pseudo_UPD, ARM::VST3LNd16_UPD, false, true, true, SingleSpc, 3, 4 ,true}, 26993032Simp{ ARM::VST3LNd32Pseudo, ARM::VST3LNd32, false, false, false, SingleSpc, 3, 2 ,true}, 2701539Srgrimes{ ARM::VST3LNd32Pseudo_UPD, ARM::VST3LNd32_UPD, false, true, true, SingleSpc, 3, 2 ,true}, 27193032Simp{ ARM::VST3LNd8Pseudo, ARM::VST3LNd8, false, false, false, SingleSpc, 3, 8 ,true}, 272150052Sstefanf{ ARM::VST3LNd8Pseudo_UPD, ARM::VST3LNd8_UPD, false, true, true, SingleSpc, 3, 8 ,true}, 273150052Sstefanf{ ARM::VST3LNq16Pseudo, ARM::VST3LNq16, false, false, false, EvenDblSpc, 3, 4,true}, 274188497Sed{ ARM::VST3LNq16Pseudo_UPD, ARM::VST3LNq16_UPD, false, true, true, EvenDblSpc, 3, 4,true}, 275188497Sed{ ARM::VST3LNq32Pseudo, ARM::VST3LNq32, false, false, false, EvenDblSpc, 3, 2,true}, 27693032Simp{ ARM::VST3LNq32Pseudo_UPD, ARM::VST3LNq32_UPD, false, true, true, EvenDblSpc, 3, 2,true}, 277228468Sed 27893032Simp{ ARM::VST3d16Pseudo, ARM::VST3d16, false, false, false, SingleSpc, 3, 4 ,true}, 2791539Srgrimes{ ARM::VST3d16Pseudo_UPD, ARM::VST3d16_UPD, false, true, true, SingleSpc, 3, 4 ,true}, 28093032Simp{ ARM::VST3d32Pseudo, ARM::VST3d32, false, false, false, SingleSpc, 3, 2 ,true}, 281153707Strhodes{ ARM::VST3d32Pseudo_UPD, ARM::VST3d32_UPD, false, true, true, SingleSpc, 3, 2 ,true}, 28293032Simp{ ARM::VST3d8Pseudo, ARM::VST3d8, false, false, false, SingleSpc, 3, 8 ,true}, 283103164Swollman{ ARM::VST3d8Pseudo_UPD, ARM::VST3d8_UPD, false, true, true, SingleSpc, 3, 8 ,true}, 284103164Swollman 28593032Simp{ ARM::VST3q16Pseudo_UPD, ARM::VST3q16_UPD, false, true, true, EvenDblSpc, 3, 4 ,true}, 28693032Simp{ ARM::VST3q16oddPseudo, ARM::VST3q16, false, false, false, OddDblSpc, 3, 4 ,true}, 28793032Simp{ ARM::VST3q16oddPseudo_UPD, ARM::VST3q16_UPD, false, true, true, OddDblSpc, 3, 4 ,true}, 288139922Stjr{ ARM::VST3q32Pseudo_UPD, ARM::VST3q32_UPD, false, true, true, EvenDblSpc, 3, 2 ,true}, 28993032Simp{ ARM::VST3q32oddPseudo, ARM::VST3q32, false, false, false, OddDblSpc, 3, 2 ,true}, 290103164Swollman{ ARM::VST3q32oddPseudo_UPD, ARM::VST3q32_UPD, false, true, true, OddDblSpc, 3, 2 ,true}, 291103164Swollman{ ARM::VST3q8Pseudo_UPD, ARM::VST3q8_UPD, false, true, true, EvenDblSpc, 3, 8 ,true}, 29293032Simp{ ARM::VST3q8oddPseudo, ARM::VST3q8, false, false, false, OddDblSpc, 3, 8 ,true}, 29393032Simp{ ARM::VST3q8oddPseudo_UPD, ARM::VST3q8_UPD, false, true, true, OddDblSpc, 3, 8 ,true}, 294156707Sandre 295156707Sandre{ ARM::VST4LNd16Pseudo, ARM::VST4LNd16, false, false, false, SingleSpc, 4, 4 ,true}, 296103728Swollman{ ARM::VST4LNd16Pseudo_UPD, ARM::VST4LNd16_UPD, false, true, true, SingleSpc, 4, 4 ,true}, 297103728Swollman{ ARM::VST4LNd32Pseudo, ARM::VST4LNd32, false, false, false, SingleSpc, 4, 2 ,true}, 298103766Sbde{ ARM::VST4LNd32Pseudo_UPD, ARM::VST4LNd32_UPD, false, true, true, SingleSpc, 4, 2 ,true}, 299103766Sbde{ ARM::VST4LNd8Pseudo, ARM::VST4LNd8, false, false, false, SingleSpc, 4, 8 ,true}, 30041927Sdt{ ARM::VST4LNd8Pseudo_UPD, ARM::VST4LNd8_UPD, false, true, true, SingleSpc, 4, 8 ,true}, 30193032Simp{ ARM::VST4LNq16Pseudo, ARM::VST4LNq16, false, false, false, EvenDblSpc, 4, 4,true}, 302126136Sache{ ARM::VST4LNq16Pseudo_UPD, ARM::VST4LNq16_UPD, false, true, true, EvenDblSpc, 4, 4,true}, 303126136Sache{ ARM::VST4LNq32Pseudo, ARM::VST4LNq32, false, false, false, EvenDblSpc, 4, 2,true}, 304103728Swollman{ ARM::VST4LNq32Pseudo_UPD, ARM::VST4LNq32_UPD, false, true, true, EvenDblSpc, 4, 2,true}, 3051539Srgrimes 3061539Srgrimes{ ARM::VST4d16Pseudo, ARM::VST4d16, false, false, false, SingleSpc, 4, 4 ,true}, 3077865Sbde{ ARM::VST4d16Pseudo_UPD, ARM::VST4d16_UPD, false, true, true, SingleSpc, 4, 4 ,true}, 308{ ARM::VST4d32Pseudo, ARM::VST4d32, false, false, false, SingleSpc, 4, 2 ,true}, 309{ ARM::VST4d32Pseudo_UPD, ARM::VST4d32_UPD, false, true, true, SingleSpc, 4, 2 ,true}, 310{ ARM::VST4d8Pseudo, ARM::VST4d8, false, false, false, SingleSpc, 4, 8 ,true}, 311{ ARM::VST4d8Pseudo_UPD, ARM::VST4d8_UPD, false, true, true, SingleSpc, 4, 8 ,true}, 312 313{ ARM::VST4q16Pseudo_UPD, ARM::VST4q16_UPD, false, true, true, EvenDblSpc, 4, 4 ,true}, 314{ ARM::VST4q16oddPseudo, ARM::VST4q16, false, false, false, OddDblSpc, 4, 4 ,true}, 315{ ARM::VST4q16oddPseudo_UPD, ARM::VST4q16_UPD, false, true, true, OddDblSpc, 4, 4 ,true}, 316{ ARM::VST4q32Pseudo_UPD, ARM::VST4q32_UPD, false, true, true, EvenDblSpc, 4, 2 ,true}, 317{ ARM::VST4q32oddPseudo, ARM::VST4q32, false, false, false, OddDblSpc, 4, 2 ,true}, 318{ ARM::VST4q32oddPseudo_UPD, ARM::VST4q32_UPD, false, true, true, OddDblSpc, 4, 2 ,true}, 319{ ARM::VST4q8Pseudo_UPD, ARM::VST4q8_UPD, false, true, true, EvenDblSpc, 4, 8 ,true}, 320{ ARM::VST4q8oddPseudo, ARM::VST4q8, false, false, false, OddDblSpc, 4, 8 ,true}, 321{ ARM::VST4q8oddPseudo_UPD, ARM::VST4q8_UPD, false, true, true, OddDblSpc, 4, 8 ,true} 322}; 323 324/// LookupNEONLdSt - Search the NEONLdStTable for information about a NEON 325/// load or store pseudo instruction. 326static const NEONLdStTableEntry *LookupNEONLdSt(unsigned Opcode) { 327 const unsigned NumEntries = array_lengthof(NEONLdStTable); 328 329#ifndef NDEBUG 330 // Make sure the table is sorted. 331 static bool TableChecked = false; 332 if (!TableChecked) { 333 for (unsigned i = 0; i != NumEntries-1; ++i) 334 assert(NEONLdStTable[i] < NEONLdStTable[i+1] && 335 "NEONLdStTable is not sorted!"); 336 TableChecked = true; 337 } 338#endif 339 340 const NEONLdStTableEntry *I = 341 std::lower_bound(NEONLdStTable, NEONLdStTable + NumEntries, Opcode); 342 if (I != NEONLdStTable + NumEntries && I->PseudoOpc == Opcode) 343 return I; 344 return NULL; 345} 346 347/// GetDSubRegs - Get 4 D subregisters of a Q, QQ, or QQQQ register, 348/// corresponding to the specified register spacing. Not all of the results 349/// are necessarily valid, e.g., a Q register only has 2 D subregisters. 350static void GetDSubRegs(unsigned Reg, NEONRegSpacing RegSpc, 351 const TargetRegisterInfo *TRI, unsigned &D0, 352 unsigned &D1, unsigned &D2, unsigned &D3) { 353 if (RegSpc == SingleSpc) { 354 D0 = TRI->getSubReg(Reg, ARM::dsub_0); 355 D1 = TRI->getSubReg(Reg, ARM::dsub_1); 356 D2 = TRI->getSubReg(Reg, ARM::dsub_2); 357 D3 = TRI->getSubReg(Reg, ARM::dsub_3); 358 } else if (RegSpc == EvenDblSpc) { 359 D0 = TRI->getSubReg(Reg, ARM::dsub_0); 360 D1 = TRI->getSubReg(Reg, ARM::dsub_2); 361 D2 = TRI->getSubReg(Reg, ARM::dsub_4); 362 D3 = TRI->getSubReg(Reg, ARM::dsub_6); 363 } else { 364 assert(RegSpc == OddDblSpc && "unknown register spacing"); 365 D0 = TRI->getSubReg(Reg, ARM::dsub_1); 366 D1 = TRI->getSubReg(Reg, ARM::dsub_3); 367 D2 = TRI->getSubReg(Reg, ARM::dsub_5); 368 D3 = TRI->getSubReg(Reg, ARM::dsub_7); 369 } 370} 371 372/// ExpandVLD - Translate VLD pseudo instructions with Q, QQ or QQQQ register 373/// operands to real VLD instructions with D register operands. 374void ARMExpandPseudo::ExpandVLD(MachineBasicBlock::iterator &MBBI) { 375 MachineInstr &MI = *MBBI; 376 MachineBasicBlock &MBB = *MI.getParent(); 377 378 const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode()); 379 assert(TableEntry && TableEntry->IsLoad && "NEONLdStTable lookup failed"); 380 NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing; 381 unsigned NumRegs = TableEntry->NumRegs; 382 383 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), 384 TII->get(TableEntry->RealOpc)); 385 unsigned OpIdx = 0; 386 387 bool DstIsDead = MI.getOperand(OpIdx).isDead(); 388 unsigned DstReg = MI.getOperand(OpIdx++).getReg(); 389 unsigned D0, D1, D2, D3; 390 GetDSubRegs(DstReg, RegSpc, TRI, D0, D1, D2, D3); 391 MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead)); 392 if (NumRegs > 1 && TableEntry->copyAllListRegs) 393 MIB.addReg(D1, RegState::Define | getDeadRegState(DstIsDead)); 394 if (NumRegs > 2 && TableEntry->copyAllListRegs) 395 MIB.addReg(D2, RegState::Define | getDeadRegState(DstIsDead)); 396 if (NumRegs > 3 && TableEntry->copyAllListRegs) 397 MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead)); 398 399 if (TableEntry->isUpdating) 400 MIB.addOperand(MI.getOperand(OpIdx++)); 401 402 // Copy the addrmode6 operands. 403 MIB.addOperand(MI.getOperand(OpIdx++)); 404 MIB.addOperand(MI.getOperand(OpIdx++)); 405 // Copy the am6offset operand. 406 if (TableEntry->hasWritebackOperand) 407 MIB.addOperand(MI.getOperand(OpIdx++)); 408 409 // For an instruction writing double-spaced subregs, the pseudo instruction 410 // has an extra operand that is a use of the super-register. Record the 411 // operand index and skip over it. 412 unsigned SrcOpIdx = 0; 413 if (RegSpc == EvenDblSpc || RegSpc == OddDblSpc) 414 SrcOpIdx = OpIdx++; 415 416 // Copy the predicate operands. 417 MIB.addOperand(MI.getOperand(OpIdx++)); 418 MIB.addOperand(MI.getOperand(OpIdx++)); 419 420 // Copy the super-register source operand used for double-spaced subregs over 421 // to the new instruction as an implicit operand. 422 if (SrcOpIdx != 0) { 423 MachineOperand MO = MI.getOperand(SrcOpIdx); 424 MO.setImplicit(true); 425 MIB.addOperand(MO); 426 } 427 // Add an implicit def for the super-register. 428 MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead)); 429 TransferImpOps(MI, MIB, MIB); 430 431 // Transfer memoperands. 432 MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 433 434 MI.eraseFromParent(); 435} 436 437/// ExpandVST - Translate VST pseudo instructions with Q, QQ or QQQQ register 438/// operands to real VST instructions with D register operands. 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 = (NEONRegSpacing)TableEntry->RegSpacing; 446 unsigned NumRegs = TableEntry->NumRegs; 447 448 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), 449 TII->get(TableEntry->RealOpc)); 450 unsigned OpIdx = 0; 451 if (TableEntry->isUpdating) 452 MIB.addOperand(MI.getOperand(OpIdx++)); 453 454 // Copy the addrmode6 operands. 455 MIB.addOperand(MI.getOperand(OpIdx++)); 456 MIB.addOperand(MI.getOperand(OpIdx++)); 457 // Copy the am6offset operand. 458 if (TableEntry->hasWritebackOperand) 459 MIB.addOperand(MI.getOperand(OpIdx++)); 460 461 bool SrcIsKill = MI.getOperand(OpIdx).isKill(); 462 bool SrcIsUndef = MI.getOperand(OpIdx).isUndef(); 463 unsigned SrcReg = MI.getOperand(OpIdx++).getReg(); 464 unsigned D0, D1, D2, D3; 465 GetDSubRegs(SrcReg, RegSpc, TRI, D0, D1, D2, D3); 466 MIB.addReg(D0, getUndefRegState(SrcIsUndef)); 467 if (NumRegs > 1 && TableEntry->copyAllListRegs) 468 MIB.addReg(D1, getUndefRegState(SrcIsUndef)); 469 if (NumRegs > 2 && TableEntry->copyAllListRegs) 470 MIB.addReg(D2, getUndefRegState(SrcIsUndef)); 471 if (NumRegs > 3 && TableEntry->copyAllListRegs) 472 MIB.addReg(D3, getUndefRegState(SrcIsUndef)); 473 474 // Copy the predicate operands. 475 MIB.addOperand(MI.getOperand(OpIdx++)); 476 MIB.addOperand(MI.getOperand(OpIdx++)); 477 478 if (SrcIsKill && !SrcIsUndef) // Add an implicit kill for the super-reg. 479 MIB->addRegisterKilled(SrcReg, TRI, true); 480 TransferImpOps(MI, MIB, MIB); 481 482 // Transfer memoperands. 483 MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 484 485 MI.eraseFromParent(); 486} 487 488/// ExpandLaneOp - Translate VLD*LN and VST*LN instructions with Q, QQ or QQQQ 489/// register operands to real instructions with D register operands. 490void ARMExpandPseudo::ExpandLaneOp(MachineBasicBlock::iterator &MBBI) { 491 MachineInstr &MI = *MBBI; 492 MachineBasicBlock &MBB = *MI.getParent(); 493 494 const NEONLdStTableEntry *TableEntry = LookupNEONLdSt(MI.getOpcode()); 495 assert(TableEntry && "NEONLdStTable lookup failed"); 496 NEONRegSpacing RegSpc = (NEONRegSpacing)TableEntry->RegSpacing; 497 unsigned NumRegs = TableEntry->NumRegs; 498 unsigned RegElts = TableEntry->RegElts; 499 500 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), 501 TII->get(TableEntry->RealOpc)); 502 unsigned OpIdx = 0; 503 // The lane operand is always the 3rd from last operand, before the 2 504 // predicate operands. 505 unsigned Lane = MI.getOperand(MI.getDesc().getNumOperands() - 3).getImm(); 506 507 // Adjust the lane and spacing as needed for Q registers. 508 assert(RegSpc != OddDblSpc && "unexpected register spacing for VLD/VST-lane"); 509 if (RegSpc == EvenDblSpc && Lane >= RegElts) { 510 RegSpc = OddDblSpc; 511 Lane -= RegElts; 512 } 513 assert(Lane < RegElts && "out of range lane for VLD/VST-lane"); 514 515 unsigned D0 = 0, D1 = 0, D2 = 0, D3 = 0; 516 unsigned DstReg = 0; 517 bool DstIsDead = false; 518 if (TableEntry->IsLoad) { 519 DstIsDead = MI.getOperand(OpIdx).isDead(); 520 DstReg = MI.getOperand(OpIdx++).getReg(); 521 GetDSubRegs(DstReg, RegSpc, TRI, D0, D1, D2, D3); 522 MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead)); 523 if (NumRegs > 1) 524 MIB.addReg(D1, RegState::Define | getDeadRegState(DstIsDead)); 525 if (NumRegs > 2) 526 MIB.addReg(D2, RegState::Define | getDeadRegState(DstIsDead)); 527 if (NumRegs > 3) 528 MIB.addReg(D3, RegState::Define | getDeadRegState(DstIsDead)); 529 } 530 531 if (TableEntry->isUpdating) 532 MIB.addOperand(MI.getOperand(OpIdx++)); 533 534 // Copy the addrmode6 operands. 535 MIB.addOperand(MI.getOperand(OpIdx++)); 536 MIB.addOperand(MI.getOperand(OpIdx++)); 537 // Copy the am6offset operand. 538 if (TableEntry->hasWritebackOperand) 539 MIB.addOperand(MI.getOperand(OpIdx++)); 540 541 // Grab the super-register source. 542 MachineOperand MO = MI.getOperand(OpIdx++); 543 if (!TableEntry->IsLoad) 544 GetDSubRegs(MO.getReg(), RegSpc, TRI, D0, D1, D2, D3); 545 546 // Add the subregs as sources of the new instruction. 547 unsigned SrcFlags = (getUndefRegState(MO.isUndef()) | 548 getKillRegState(MO.isKill())); 549 MIB.addReg(D0, SrcFlags); 550 if (NumRegs > 1) 551 MIB.addReg(D1, SrcFlags); 552 if (NumRegs > 2) 553 MIB.addReg(D2, SrcFlags); 554 if (NumRegs > 3) 555 MIB.addReg(D3, SrcFlags); 556 557 // Add the lane number operand. 558 MIB.addImm(Lane); 559 OpIdx += 1; 560 561 // Copy the predicate operands. 562 MIB.addOperand(MI.getOperand(OpIdx++)); 563 MIB.addOperand(MI.getOperand(OpIdx++)); 564 565 // Copy the super-register source to be an implicit source. 566 MO.setImplicit(true); 567 MIB.addOperand(MO); 568 if (TableEntry->IsLoad) 569 // Add an implicit def for the super-register. 570 MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead)); 571 TransferImpOps(MI, MIB, MIB); 572 // Transfer memoperands. 573 MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 574 MI.eraseFromParent(); 575} 576 577/// ExpandVTBL - Translate VTBL and VTBX pseudo instructions with Q or QQ 578/// register operands to real instructions with D register operands. 579void ARMExpandPseudo::ExpandVTBL(MachineBasicBlock::iterator &MBBI, 580 unsigned Opc, bool IsExt) { 581 MachineInstr &MI = *MBBI; 582 MachineBasicBlock &MBB = *MI.getParent(); 583 584 MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)); 585 unsigned OpIdx = 0; 586 587 // Transfer the destination register operand. 588 MIB.addOperand(MI.getOperand(OpIdx++)); 589 if (IsExt) 590 MIB.addOperand(MI.getOperand(OpIdx++)); 591 592 bool SrcIsKill = MI.getOperand(OpIdx).isKill(); 593 unsigned SrcReg = MI.getOperand(OpIdx++).getReg(); 594 unsigned D0, D1, D2, D3; 595 GetDSubRegs(SrcReg, SingleSpc, TRI, D0, D1, D2, D3); 596 MIB.addReg(D0); 597 598 // Copy the other source register operand. 599 MIB.addOperand(MI.getOperand(OpIdx++)); 600 601 // Copy the predicate operands. 602 MIB.addOperand(MI.getOperand(OpIdx++)); 603 MIB.addOperand(MI.getOperand(OpIdx++)); 604 605 if (SrcIsKill) // Add an implicit kill for the super-reg. 606 MIB->addRegisterKilled(SrcReg, TRI, true); 607 TransferImpOps(MI, MIB, MIB); 608 MI.eraseFromParent(); 609} 610 611void ARMExpandPseudo::ExpandMOV32BitImm(MachineBasicBlock &MBB, 612 MachineBasicBlock::iterator &MBBI) { 613 MachineInstr &MI = *MBBI; 614 unsigned Opcode = MI.getOpcode(); 615 unsigned PredReg = 0; 616 ARMCC::CondCodes Pred = getInstrPredicate(&MI, PredReg); 617 unsigned DstReg = MI.getOperand(0).getReg(); 618 bool DstIsDead = MI.getOperand(0).isDead(); 619 bool isCC = Opcode == ARM::MOVCCi32imm || Opcode == ARM::t2MOVCCi32imm; 620 const MachineOperand &MO = MI.getOperand(isCC ? 2 : 1); 621 MachineInstrBuilder LO16, HI16; 622 623 if (!STI->hasV6T2Ops() && 624 (Opcode == ARM::MOVi32imm || Opcode == ARM::MOVCCi32imm)) { 625 // Expand into a movi + orr. 626 LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVi), DstReg); 627 HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::ORRri)) 628 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 629 .addReg(DstReg); 630 631 assert (MO.isImm() && "MOVi32imm w/ non-immediate source operand!"); 632 unsigned ImmVal = (unsigned)MO.getImm(); 633 unsigned SOImmValV1 = ARM_AM::getSOImmTwoPartFirst(ImmVal); 634 unsigned SOImmValV2 = ARM_AM::getSOImmTwoPartSecond(ImmVal); 635 LO16 = LO16.addImm(SOImmValV1); 636 HI16 = HI16.addImm(SOImmValV2); 637 LO16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 638 HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 639 LO16.addImm(Pred).addReg(PredReg).addReg(0); 640 HI16.addImm(Pred).addReg(PredReg).addReg(0); 641 TransferImpOps(MI, LO16, HI16); 642 MI.eraseFromParent(); 643 return; 644 } 645 646 unsigned LO16Opc = 0; 647 unsigned HI16Opc = 0; 648 if (Opcode == ARM::t2MOVi32imm || Opcode == ARM::t2MOVCCi32imm) { 649 LO16Opc = ARM::t2MOVi16; 650 HI16Opc = ARM::t2MOVTi16; 651 } else { 652 LO16Opc = ARM::MOVi16; 653 HI16Opc = ARM::MOVTi16; 654 } 655 656 LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(LO16Opc), DstReg); 657 HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(HI16Opc)) 658 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 659 .addReg(DstReg); 660 661 if (MO.isImm()) { 662 unsigned Imm = MO.getImm(); 663 unsigned Lo16 = Imm & 0xffff; 664 unsigned Hi16 = (Imm >> 16) & 0xffff; 665 LO16 = LO16.addImm(Lo16); 666 HI16 = HI16.addImm(Hi16); 667 } else { 668 const GlobalValue *GV = MO.getGlobal(); 669 unsigned TF = MO.getTargetFlags(); 670 LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16); 671 HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16); 672 } 673 674 LO16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 675 HI16->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 676 LO16.addImm(Pred).addReg(PredReg); 677 HI16.addImm(Pred).addReg(PredReg); 678 679 TransferImpOps(MI, LO16, HI16); 680 MI.eraseFromParent(); 681} 682 683bool ARMExpandPseudo::ExpandMI(MachineBasicBlock &MBB, 684 MachineBasicBlock::iterator MBBI) { 685 MachineInstr &MI = *MBBI; 686 unsigned Opcode = MI.getOpcode(); 687 switch (Opcode) { 688 default: 689 return false; 690 case ARM::VMOVScc: 691 case ARM::VMOVDcc: { 692 unsigned newOpc = Opcode == ARM::VMOVScc ? ARM::VMOVS : ARM::VMOVD; 693 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(newOpc), 694 MI.getOperand(1).getReg()) 695 .addOperand(MI.getOperand(2)) 696 .addImm(MI.getOperand(3).getImm()) // 'pred' 697 .addOperand(MI.getOperand(4)); 698 699 MI.eraseFromParent(); 700 return true; 701 } 702 case ARM::t2MOVCCr: 703 case ARM::MOVCCr: { 704 unsigned Opc = AFI->isThumbFunction() ? ARM::t2MOVr : ARM::MOVr; 705 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc), 706 MI.getOperand(1).getReg()) 707 .addOperand(MI.getOperand(2)) 708 .addImm(MI.getOperand(3).getImm()) // 'pred' 709 .addOperand(MI.getOperand(4)) 710 .addReg(0); // 's' bit 711 712 MI.eraseFromParent(); 713 return true; 714 } 715 case ARM::MOVCCsi: { 716 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi), 717 (MI.getOperand(1).getReg())) 718 .addOperand(MI.getOperand(2)) 719 .addImm(MI.getOperand(3).getImm()) 720 .addImm(MI.getOperand(4).getImm()) // 'pred' 721 .addOperand(MI.getOperand(5)) 722 .addReg(0); // 's' bit 723 724 MI.eraseFromParent(); 725 return true; 726 } 727 case ARM::MOVCCsr: { 728 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsr), 729 (MI.getOperand(1).getReg())) 730 .addOperand(MI.getOperand(2)) 731 .addOperand(MI.getOperand(3)) 732 .addImm(MI.getOperand(4).getImm()) 733 .addImm(MI.getOperand(5).getImm()) // 'pred' 734 .addOperand(MI.getOperand(6)) 735 .addReg(0); // 's' bit 736 737 MI.eraseFromParent(); 738 return true; 739 } 740 case ARM::t2MOVCCi16: 741 case ARM::MOVCCi16: { 742 unsigned NewOpc = AFI->isThumbFunction() ? ARM::t2MOVi16 : ARM::MOVi16; 743 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc), 744 MI.getOperand(1).getReg()) 745 .addImm(MI.getOperand(2).getImm()) 746 .addImm(MI.getOperand(3).getImm()) // 'pred' 747 .addOperand(MI.getOperand(4)); 748 MI.eraseFromParent(); 749 return true; 750 } 751 case ARM::t2MOVCCi: 752 case ARM::MOVCCi: { 753 unsigned Opc = AFI->isThumbFunction() ? ARM::t2MOVi : ARM::MOVi; 754 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc), 755 MI.getOperand(1).getReg()) 756 .addImm(MI.getOperand(2).getImm()) 757 .addImm(MI.getOperand(3).getImm()) // 'pred' 758 .addOperand(MI.getOperand(4)) 759 .addReg(0); // 's' bit 760 761 MI.eraseFromParent(); 762 return true; 763 } 764 case ARM::t2MVNCCi: 765 case ARM::MVNCCi: { 766 unsigned Opc = AFI->isThumbFunction() ? ARM::t2MVNi : ARM::MVNi; 767 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc), 768 MI.getOperand(1).getReg()) 769 .addImm(MI.getOperand(2).getImm()) 770 .addImm(MI.getOperand(3).getImm()) // 'pred' 771 .addOperand(MI.getOperand(4)) 772 .addReg(0); // 's' bit 773 774 MI.eraseFromParent(); 775 return true; 776 } 777 case ARM::t2MOVCClsl: 778 case ARM::t2MOVCClsr: 779 case ARM::t2MOVCCasr: 780 case ARM::t2MOVCCror: { 781 unsigned NewOpc; 782 switch (Opcode) { 783 case ARM::t2MOVCClsl: NewOpc = ARM::t2LSLri; break; 784 case ARM::t2MOVCClsr: NewOpc = ARM::t2LSRri; break; 785 case ARM::t2MOVCCasr: NewOpc = ARM::t2ASRri; break; 786 case ARM::t2MOVCCror: NewOpc = ARM::t2RORri; break; 787 default: llvm_unreachable("unexpeced conditional move"); 788 } 789 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc), 790 MI.getOperand(1).getReg()) 791 .addOperand(MI.getOperand(2)) 792 .addImm(MI.getOperand(3).getImm()) 793 .addImm(MI.getOperand(4).getImm()) // 'pred' 794 .addOperand(MI.getOperand(5)) 795 .addReg(0); // 's' bit 796 MI.eraseFromParent(); 797 return true; 798 } 799 case ARM::Int_eh_sjlj_dispatchsetup: { 800 MachineFunction &MF = *MI.getParent()->getParent(); 801 const ARMBaseInstrInfo *AII = 802 static_cast<const ARMBaseInstrInfo*>(TII); 803 const ARMBaseRegisterInfo &RI = AII->getRegisterInfo(); 804 // For functions using a base pointer, we rematerialize it (via the frame 805 // pointer) here since eh.sjlj.setjmp and eh.sjlj.longjmp don't do it 806 // for us. Otherwise, expand to nothing. 807 if (RI.hasBasePointer(MF)) { 808 int32_t NumBytes = AFI->getFramePtrSpillOffset(); 809 unsigned FramePtr = RI.getFrameRegister(MF); 810 assert(MF.getTarget().getFrameLowering()->hasFP(MF) && 811 "base pointer without frame pointer?"); 812 813 if (AFI->isThumb2Function()) { 814 emitT2RegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6, 815 FramePtr, -NumBytes, ARMCC::AL, 0, *TII); 816 } else if (AFI->isThumbFunction()) { 817 emitThumbRegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6, 818 FramePtr, -NumBytes, *TII, RI); 819 } else { 820 emitARMRegPlusImmediate(MBB, MBBI, MI.getDebugLoc(), ARM::R6, 821 FramePtr, -NumBytes, ARMCC::AL, 0, 822 *TII); 823 } 824 // If there's dynamic realignment, adjust for it. 825 if (RI.needsStackRealignment(MF)) { 826 MachineFrameInfo *MFI = MF.getFrameInfo(); 827 unsigned MaxAlign = MFI->getMaxAlignment(); 828 assert (!AFI->isThumb1OnlyFunction()); 829 // Emit bic r6, r6, MaxAlign 830 unsigned bicOpc = AFI->isThumbFunction() ? 831 ARM::t2BICri : ARM::BICri; 832 AddDefaultCC(AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), 833 TII->get(bicOpc), ARM::R6) 834 .addReg(ARM::R6, RegState::Kill) 835 .addImm(MaxAlign-1))); 836 } 837 838 } 839 MI.eraseFromParent(); 840 return true; 841 } 842 843 case ARM::MOVsrl_flag: 844 case ARM::MOVsra_flag: { 845 // These are just fancy MOVs instructions. 846 AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::MOVsi), 847 MI.getOperand(0).getReg()) 848 .addOperand(MI.getOperand(1)) 849 .addImm(ARM_AM::getSORegOpc((Opcode == ARM::MOVsrl_flag ? 850 ARM_AM::lsr : ARM_AM::asr), 851 1))) 852 .addReg(ARM::CPSR, RegState::Define); 853 MI.eraseFromParent(); 854 return true; 855 } 856 case ARM::RRX: { 857 // This encodes as "MOVs Rd, Rm, rrx 858 MachineInstrBuilder MIB = 859 AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(),TII->get(ARM::MOVsi), 860 MI.getOperand(0).getReg()) 861 .addOperand(MI.getOperand(1)) 862 .addImm(ARM_AM::getSORegOpc(ARM_AM::rrx, 0))) 863 .addReg(0); 864 TransferImpOps(MI, MIB, MIB); 865 MI.eraseFromParent(); 866 return true; 867 } 868 case ARM::tTPsoft: 869 case ARM::TPsoft: { 870 MachineInstrBuilder MIB = 871 BuildMI(MBB, MBBI, MI.getDebugLoc(), 872 TII->get(Opcode == ARM::tTPsoft ? ARM::tBL : ARM::BL)) 873 .addExternalSymbol("__aeabi_read_tp", 0); 874 875 MIB->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 876 TransferImpOps(MI, MIB, MIB); 877 MI.eraseFromParent(); 878 return true; 879 } 880 case ARM::tLDRpci_pic: 881 case ARM::t2LDRpci_pic: { 882 unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic) 883 ? ARM::tLDRpci : ARM::t2LDRpci; 884 unsigned DstReg = MI.getOperand(0).getReg(); 885 bool DstIsDead = MI.getOperand(0).isDead(); 886 MachineInstrBuilder MIB1 = 887 AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), 888 TII->get(NewLdOpc), DstReg) 889 .addOperand(MI.getOperand(1))); 890 MIB1->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 891 MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(), 892 TII->get(ARM::tPICADD)) 893 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 894 .addReg(DstReg) 895 .addOperand(MI.getOperand(2)); 896 TransferImpOps(MI, MIB1, MIB2); 897 MI.eraseFromParent(); 898 return true; 899 } 900 901 case ARM::MOV_ga_dyn: 902 case ARM::MOV_ga_pcrel: 903 case ARM::MOV_ga_pcrel_ldr: 904 case ARM::t2MOV_ga_dyn: 905 case ARM::t2MOV_ga_pcrel: { 906 // Expand into movw + movw. Also "add pc" / ldr [pc] in PIC mode. 907 unsigned LabelId = AFI->createPICLabelUId(); 908 unsigned DstReg = MI.getOperand(0).getReg(); 909 bool DstIsDead = MI.getOperand(0).isDead(); 910 const MachineOperand &MO1 = MI.getOperand(1); 911 const GlobalValue *GV = MO1.getGlobal(); 912 unsigned TF = MO1.getTargetFlags(); 913 bool isARM = (Opcode != ARM::t2MOV_ga_pcrel && Opcode!=ARM::t2MOV_ga_dyn); 914 bool isPIC = (Opcode != ARM::MOV_ga_dyn && Opcode != ARM::t2MOV_ga_dyn); 915 unsigned LO16Opc = isARM ? ARM::MOVi16_ga_pcrel : ARM::t2MOVi16_ga_pcrel; 916 unsigned HI16Opc = isARM ? ARM::MOVTi16_ga_pcrel :ARM::t2MOVTi16_ga_pcrel; 917 unsigned LO16TF = isPIC 918 ? ARMII::MO_LO16_NONLAZY_PIC : ARMII::MO_LO16_NONLAZY; 919 unsigned HI16TF = isPIC 920 ? ARMII::MO_HI16_NONLAZY_PIC : ARMII::MO_HI16_NONLAZY; 921 unsigned PICAddOpc = isARM 922 ? (Opcode == ARM::MOV_ga_pcrel_ldr ? ARM::PICLDR : ARM::PICADD) 923 : ARM::tPICADD; 924 MachineInstrBuilder MIB1 = BuildMI(MBB, MBBI, MI.getDebugLoc(), 925 TII->get(LO16Opc), DstReg) 926 .addGlobalAddress(GV, MO1.getOffset(), TF | LO16TF) 927 .addImm(LabelId); 928 MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(), 929 TII->get(HI16Opc), DstReg) 930 .addReg(DstReg) 931 .addGlobalAddress(GV, MO1.getOffset(), TF | HI16TF) 932 .addImm(LabelId); 933 if (!isPIC) { 934 TransferImpOps(MI, MIB1, MIB2); 935 MI.eraseFromParent(); 936 return true; 937 } 938 939 MachineInstrBuilder MIB3 = BuildMI(MBB, MBBI, MI.getDebugLoc(), 940 TII->get(PICAddOpc)) 941 .addReg(DstReg, RegState::Define | getDeadRegState(DstIsDead)) 942 .addReg(DstReg).addImm(LabelId); 943 if (isARM) { 944 AddDefaultPred(MIB3); 945 if (Opcode == ARM::MOV_ga_pcrel_ldr) 946 MIB3->setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 947 } 948 TransferImpOps(MI, MIB1, MIB3); 949 MI.eraseFromParent(); 950 return true; 951 } 952 953 case ARM::MOVi32imm: 954 case ARM::MOVCCi32imm: 955 case ARM::t2MOVi32imm: 956 case ARM::t2MOVCCi32imm: 957 ExpandMOV32BitImm(MBB, MBBI); 958 return true; 959 960 case ARM::SUBS_PC_LR: { 961 MachineInstrBuilder MIB = 962 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::SUBri), ARM::PC) 963 .addReg(ARM::LR) 964 .addOperand(MI.getOperand(0)) 965 .addOperand(MI.getOperand(1)) 966 .addOperand(MI.getOperand(2)) 967 .addReg(ARM::CPSR, RegState::Undef); 968 TransferImpOps(MI, MIB, MIB); 969 MI.eraseFromParent(); 970 return true; 971 } 972 case ARM::VLDMQIA: { 973 unsigned NewOpc = ARM::VLDMDIA; 974 MachineInstrBuilder MIB = 975 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc)); 976 unsigned OpIdx = 0; 977 978 // Grab the Q register destination. 979 bool DstIsDead = MI.getOperand(OpIdx).isDead(); 980 unsigned DstReg = MI.getOperand(OpIdx++).getReg(); 981 982 // Copy the source register. 983 MIB.addOperand(MI.getOperand(OpIdx++)); 984 985 // Copy the predicate operands. 986 MIB.addOperand(MI.getOperand(OpIdx++)); 987 MIB.addOperand(MI.getOperand(OpIdx++)); 988 989 // Add the destination operands (D subregs). 990 unsigned D0 = TRI->getSubReg(DstReg, ARM::dsub_0); 991 unsigned D1 = TRI->getSubReg(DstReg, ARM::dsub_1); 992 MIB.addReg(D0, RegState::Define | getDeadRegState(DstIsDead)) 993 .addReg(D1, RegState::Define | getDeadRegState(DstIsDead)); 994 995 // Add an implicit def for the super-register. 996 MIB.addReg(DstReg, RegState::ImplicitDefine | getDeadRegState(DstIsDead)); 997 TransferImpOps(MI, MIB, MIB); 998 MIB.setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 999 MI.eraseFromParent(); 1000 return true; 1001 } 1002 1003 case ARM::VSTMQIA: { 1004 unsigned NewOpc = ARM::VSTMDIA; 1005 MachineInstrBuilder MIB = 1006 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc)); 1007 unsigned OpIdx = 0; 1008 1009 // Grab the Q register source. 1010 bool SrcIsKill = MI.getOperand(OpIdx).isKill(); 1011 unsigned SrcReg = MI.getOperand(OpIdx++).getReg(); 1012 1013 // Copy the destination register. 1014 MIB.addOperand(MI.getOperand(OpIdx++)); 1015 1016 // Copy the predicate operands. 1017 MIB.addOperand(MI.getOperand(OpIdx++)); 1018 MIB.addOperand(MI.getOperand(OpIdx++)); 1019 1020 // Add the source operands (D subregs). 1021 unsigned D0 = TRI->getSubReg(SrcReg, ARM::dsub_0); 1022 unsigned D1 = TRI->getSubReg(SrcReg, ARM::dsub_1); 1023 MIB.addReg(D0).addReg(D1); 1024 1025 if (SrcIsKill) // Add an implicit kill for the Q register. 1026 MIB->addRegisterKilled(SrcReg, TRI, true); 1027 1028 TransferImpOps(MI, MIB, MIB); 1029 MIB.setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 1030 MI.eraseFromParent(); 1031 return true; 1032 } 1033 case ARM::VDUPfqf: 1034 case ARM::VDUPfdf:{ 1035 unsigned NewOpc = Opcode == ARM::VDUPfqf ? ARM::VDUPLN32q : 1036 ARM::VDUPLN32d; 1037 MachineInstrBuilder MIB = 1038 BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(NewOpc)); 1039 unsigned OpIdx = 0; 1040 unsigned SrcReg = MI.getOperand(1).getReg(); 1041 unsigned Lane = TRI->getEncodingValue(SrcReg) & 1; 1042 unsigned DReg = TRI->getMatchingSuperReg(SrcReg, 1043 Lane & 1 ? ARM::ssub_1 : ARM::ssub_0, 1044 &ARM::DPR_VFP2RegClass); 1045 // The lane is [0,1] for the containing DReg superregister. 1046 // Copy the dst/src register operands. 1047 MIB.addOperand(MI.getOperand(OpIdx++)); 1048 MIB.addReg(DReg); 1049 ++OpIdx; 1050 // Add the lane select operand. 1051 MIB.addImm(Lane); 1052 // Add the predicate operands. 1053 MIB.addOperand(MI.getOperand(OpIdx++)); 1054 MIB.addOperand(MI.getOperand(OpIdx++)); 1055 1056 TransferImpOps(MI, MIB, MIB); 1057 MI.eraseFromParent(); 1058 return true; 1059 } 1060 1061 case ARM::VLD2q8Pseudo: 1062 case ARM::VLD2q16Pseudo: 1063 case ARM::VLD2q32Pseudo: 1064 case ARM::VLD2q8PseudoWB_fixed: 1065 case ARM::VLD2q16PseudoWB_fixed: 1066 case ARM::VLD2q32PseudoWB_fixed: 1067 case ARM::VLD2q8PseudoWB_register: 1068 case ARM::VLD2q16PseudoWB_register: 1069 case ARM::VLD2q32PseudoWB_register: 1070 case ARM::VLD3d8Pseudo: 1071 case ARM::VLD3d16Pseudo: 1072 case ARM::VLD3d32Pseudo: 1073 case ARM::VLD1d64TPseudo: 1074 case ARM::VLD3d8Pseudo_UPD: 1075 case ARM::VLD3d16Pseudo_UPD: 1076 case ARM::VLD3d32Pseudo_UPD: 1077 case ARM::VLD3q8Pseudo_UPD: 1078 case ARM::VLD3q16Pseudo_UPD: 1079 case ARM::VLD3q32Pseudo_UPD: 1080 case ARM::VLD3q8oddPseudo: 1081 case ARM::VLD3q16oddPseudo: 1082 case ARM::VLD3q32oddPseudo: 1083 case ARM::VLD3q8oddPseudo_UPD: 1084 case ARM::VLD3q16oddPseudo_UPD: 1085 case ARM::VLD3q32oddPseudo_UPD: 1086 case ARM::VLD4d8Pseudo: 1087 case ARM::VLD4d16Pseudo: 1088 case ARM::VLD4d32Pseudo: 1089 case ARM::VLD1d64QPseudo: 1090 case ARM::VLD4d8Pseudo_UPD: 1091 case ARM::VLD4d16Pseudo_UPD: 1092 case ARM::VLD4d32Pseudo_UPD: 1093 case ARM::VLD4q8Pseudo_UPD: 1094 case ARM::VLD4q16Pseudo_UPD: 1095 case ARM::VLD4q32Pseudo_UPD: 1096 case ARM::VLD4q8oddPseudo: 1097 case ARM::VLD4q16oddPseudo: 1098 case ARM::VLD4q32oddPseudo: 1099 case ARM::VLD4q8oddPseudo_UPD: 1100 case ARM::VLD4q16oddPseudo_UPD: 1101 case ARM::VLD4q32oddPseudo_UPD: 1102 case ARM::VLD3DUPd8Pseudo: 1103 case ARM::VLD3DUPd16Pseudo: 1104 case ARM::VLD3DUPd32Pseudo: 1105 case ARM::VLD3DUPd8Pseudo_UPD: 1106 case ARM::VLD3DUPd16Pseudo_UPD: 1107 case ARM::VLD3DUPd32Pseudo_UPD: 1108 case ARM::VLD4DUPd8Pseudo: 1109 case ARM::VLD4DUPd16Pseudo: 1110 case ARM::VLD4DUPd32Pseudo: 1111 case ARM::VLD4DUPd8Pseudo_UPD: 1112 case ARM::VLD4DUPd16Pseudo_UPD: 1113 case ARM::VLD4DUPd32Pseudo_UPD: 1114 ExpandVLD(MBBI); 1115 return true; 1116 1117 case ARM::VST2q8Pseudo: 1118 case ARM::VST2q16Pseudo: 1119 case ARM::VST2q32Pseudo: 1120 case ARM::VST2q8PseudoWB_fixed: 1121 case ARM::VST2q16PseudoWB_fixed: 1122 case ARM::VST2q32PseudoWB_fixed: 1123 case ARM::VST2q8PseudoWB_register: 1124 case ARM::VST2q16PseudoWB_register: 1125 case ARM::VST2q32PseudoWB_register: 1126 case ARM::VST3d8Pseudo: 1127 case ARM::VST3d16Pseudo: 1128 case ARM::VST3d32Pseudo: 1129 case ARM::VST1d64TPseudo: 1130 case ARM::VST3d8Pseudo_UPD: 1131 case ARM::VST3d16Pseudo_UPD: 1132 case ARM::VST3d32Pseudo_UPD: 1133 case ARM::VST1d64TPseudoWB_fixed: 1134 case ARM::VST1d64TPseudoWB_register: 1135 case ARM::VST3q8Pseudo_UPD: 1136 case ARM::VST3q16Pseudo_UPD: 1137 case ARM::VST3q32Pseudo_UPD: 1138 case ARM::VST3q8oddPseudo: 1139 case ARM::VST3q16oddPseudo: 1140 case ARM::VST3q32oddPseudo: 1141 case ARM::VST3q8oddPseudo_UPD: 1142 case ARM::VST3q16oddPseudo_UPD: 1143 case ARM::VST3q32oddPseudo_UPD: 1144 case ARM::VST4d8Pseudo: 1145 case ARM::VST4d16Pseudo: 1146 case ARM::VST4d32Pseudo: 1147 case ARM::VST1d64QPseudo: 1148 case ARM::VST4d8Pseudo_UPD: 1149 case ARM::VST4d16Pseudo_UPD: 1150 case ARM::VST4d32Pseudo_UPD: 1151 case ARM::VST1d64QPseudoWB_fixed: 1152 case ARM::VST1d64QPseudoWB_register: 1153 case ARM::VST4q8Pseudo_UPD: 1154 case ARM::VST4q16Pseudo_UPD: 1155 case ARM::VST4q32Pseudo_UPD: 1156 case ARM::VST4q8oddPseudo: 1157 case ARM::VST4q16oddPseudo: 1158 case ARM::VST4q32oddPseudo: 1159 case ARM::VST4q8oddPseudo_UPD: 1160 case ARM::VST4q16oddPseudo_UPD: 1161 case ARM::VST4q32oddPseudo_UPD: 1162 ExpandVST(MBBI); 1163 return true; 1164 1165 case ARM::VLD1LNq8Pseudo: 1166 case ARM::VLD1LNq16Pseudo: 1167 case ARM::VLD1LNq32Pseudo: 1168 case ARM::VLD1LNq8Pseudo_UPD: 1169 case ARM::VLD1LNq16Pseudo_UPD: 1170 case ARM::VLD1LNq32Pseudo_UPD: 1171 case ARM::VLD2LNd8Pseudo: 1172 case ARM::VLD2LNd16Pseudo: 1173 case ARM::VLD2LNd32Pseudo: 1174 case ARM::VLD2LNq16Pseudo: 1175 case ARM::VLD2LNq32Pseudo: 1176 case ARM::VLD2LNd8Pseudo_UPD: 1177 case ARM::VLD2LNd16Pseudo_UPD: 1178 case ARM::VLD2LNd32Pseudo_UPD: 1179 case ARM::VLD2LNq16Pseudo_UPD: 1180 case ARM::VLD2LNq32Pseudo_UPD: 1181 case ARM::VLD3LNd8Pseudo: 1182 case ARM::VLD3LNd16Pseudo: 1183 case ARM::VLD3LNd32Pseudo: 1184 case ARM::VLD3LNq16Pseudo: 1185 case ARM::VLD3LNq32Pseudo: 1186 case ARM::VLD3LNd8Pseudo_UPD: 1187 case ARM::VLD3LNd16Pseudo_UPD: 1188 case ARM::VLD3LNd32Pseudo_UPD: 1189 case ARM::VLD3LNq16Pseudo_UPD: 1190 case ARM::VLD3LNq32Pseudo_UPD: 1191 case ARM::VLD4LNd8Pseudo: 1192 case ARM::VLD4LNd16Pseudo: 1193 case ARM::VLD4LNd32Pseudo: 1194 case ARM::VLD4LNq16Pseudo: 1195 case ARM::VLD4LNq32Pseudo: 1196 case ARM::VLD4LNd8Pseudo_UPD: 1197 case ARM::VLD4LNd16Pseudo_UPD: 1198 case ARM::VLD4LNd32Pseudo_UPD: 1199 case ARM::VLD4LNq16Pseudo_UPD: 1200 case ARM::VLD4LNq32Pseudo_UPD: 1201 case ARM::VST1LNq8Pseudo: 1202 case ARM::VST1LNq16Pseudo: 1203 case ARM::VST1LNq32Pseudo: 1204 case ARM::VST1LNq8Pseudo_UPD: 1205 case ARM::VST1LNq16Pseudo_UPD: 1206 case ARM::VST1LNq32Pseudo_UPD: 1207 case ARM::VST2LNd8Pseudo: 1208 case ARM::VST2LNd16Pseudo: 1209 case ARM::VST2LNd32Pseudo: 1210 case ARM::VST2LNq16Pseudo: 1211 case ARM::VST2LNq32Pseudo: 1212 case ARM::VST2LNd8Pseudo_UPD: 1213 case ARM::VST2LNd16Pseudo_UPD: 1214 case ARM::VST2LNd32Pseudo_UPD: 1215 case ARM::VST2LNq16Pseudo_UPD: 1216 case ARM::VST2LNq32Pseudo_UPD: 1217 case ARM::VST3LNd8Pseudo: 1218 case ARM::VST3LNd16Pseudo: 1219 case ARM::VST3LNd32Pseudo: 1220 case ARM::VST3LNq16Pseudo: 1221 case ARM::VST3LNq32Pseudo: 1222 case ARM::VST3LNd8Pseudo_UPD: 1223 case ARM::VST3LNd16Pseudo_UPD: 1224 case ARM::VST3LNd32Pseudo_UPD: 1225 case ARM::VST3LNq16Pseudo_UPD: 1226 case ARM::VST3LNq32Pseudo_UPD: 1227 case ARM::VST4LNd8Pseudo: 1228 case ARM::VST4LNd16Pseudo: 1229 case ARM::VST4LNd32Pseudo: 1230 case ARM::VST4LNq16Pseudo: 1231 case ARM::VST4LNq32Pseudo: 1232 case ARM::VST4LNd8Pseudo_UPD: 1233 case ARM::VST4LNd16Pseudo_UPD: 1234 case ARM::VST4LNd32Pseudo_UPD: 1235 case ARM::VST4LNq16Pseudo_UPD: 1236 case ARM::VST4LNq32Pseudo_UPD: 1237 ExpandLaneOp(MBBI); 1238 return true; 1239 1240 case ARM::VTBL3Pseudo: ExpandVTBL(MBBI, ARM::VTBL3, false); return true; 1241 case ARM::VTBL4Pseudo: ExpandVTBL(MBBI, ARM::VTBL4, false); return true; 1242 case ARM::VTBX3Pseudo: ExpandVTBL(MBBI, ARM::VTBX3, true); return true; 1243 case ARM::VTBX4Pseudo: ExpandVTBL(MBBI, ARM::VTBX4, true); return true; 1244 } 1245} 1246 1247bool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { 1248 bool Modified = false; 1249 1250 MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 1251 while (MBBI != E) { 1252 MachineBasicBlock::iterator NMBBI = llvm::next(MBBI); 1253 Modified |= ExpandMI(MBB, MBBI); 1254 MBBI = NMBBI; 1255 } 1256 1257 return Modified; 1258} 1259 1260bool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 1261 const TargetMachine &TM = MF.getTarget(); 1262 TII = static_cast<const ARMBaseInstrInfo*>(TM.getInstrInfo()); 1263 TRI = TM.getRegisterInfo(); 1264 STI = &TM.getSubtarget<ARMSubtarget>(); 1265 AFI = MF.getInfo<ARMFunctionInfo>(); 1266 1267 bool Modified = false; 1268 for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E; 1269 ++MFI) 1270 Modified |= ExpandMBB(*MFI); 1271 if (VerifyARMPseudo) 1272 MF.verify(this, "After expanding ARM pseudo instructions."); 1273 return Modified; 1274} 1275 1276/// createARMExpandPseudoPass - returns an instance of the pseudo instruction 1277/// expansion pass. 1278FunctionPass *llvm::createARMExpandPseudoPass() { 1279 return new ARMExpandPseudo(); 1280} 1281