ARMExpandPseudoInsts.cpp revision e5ce4f68c786696a96acf1f1aa5431652abb6ce7
1b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng//===-- ARMExpandPseudoInsts.cpp - Expand pseudo instructions -----*- C++ -*-=// 2b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 3b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// The LLVM Compiler Infrastructure 4b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 5b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// This file is distributed under the University of Illinois Open Source 6b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// License. See LICENSE.TXT for details. 7b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 8b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng//===----------------------------------------------------------------------===// 9b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 10b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// This file contains a pass that expand pseudo instructions into target 11b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// instructions to allow proper scheduling, if-conversion, and other late 12b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// optimizations. This pass should be run after register allocation but before 13b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// post- regalloc scheduling pass. 14b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng// 15b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng//===----------------------------------------------------------------------===// 16b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 17b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#define DEBUG_TYPE "arm-pseudo" 18b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "ARM.h" 19b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "ARMBaseInstrInfo.h" 20b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "llvm/CodeGen/MachineFunctionPass.h" 21b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng#include "llvm/CodeGen/MachineInstrBuilder.h" 224dbbe3433f7339ed277af55037ff6847f484e5abChris Lattner#include "llvm/Target/TargetRegisterInfo.h" 23b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Chengusing namespace llvm; 24b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 25b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Chengnamespace { 26b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng class ARMExpandPseudo : public MachineFunctionPass { 27709d59255a3100c7d440c93069efa1f726677a27Bob Wilson // Constants for register spacing in NEON load/store instructions. 28709d59255a3100c7d440c93069efa1f726677a27Bob Wilson enum NEONRegSpacing { 29709d59255a3100c7d440c93069efa1f726677a27Bob Wilson SingleSpc, 30709d59255a3100c7d440c93069efa1f726677a27Bob Wilson EvenDblSpc, 31709d59255a3100c7d440c93069efa1f726677a27Bob Wilson OddDblSpc 32709d59255a3100c7d440c93069efa1f726677a27Bob Wilson }; 33709d59255a3100c7d440c93069efa1f726677a27Bob Wilson 34b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng public: 35b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng static char ID; 3690c579de5a383cee278acc3f7e7b9d0a656e6a35Owen Anderson ARMExpandPseudo() : MachineFunctionPass(ID) {} 37b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 38b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng const TargetInstrInfo *TII; 39d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng const TargetRegisterInfo *TRI; 40b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 41b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng virtual bool runOnMachineFunction(MachineFunction &Fn); 42b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 43b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng virtual const char *getPassName() const { 44b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng return "ARM pseudo instruction expansion pass"; 45b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 46b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 47b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng private: 48431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng void TransferImpOps(MachineInstr &OldMI, 49431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder &UseMI, MachineInstrBuilder &DefMI); 50b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng bool ExpandMBB(MachineBasicBlock &MBB); 5101ba461af7eafc9d181a5c349487691f2e801438Bob Wilson void ExpandVST(MachineBasicBlock::iterator &MBBI, unsigned Opc, 5201ba461af7eafc9d181a5c349487691f2e801438Bob Wilson bool hasWriteBack, NEONRegSpacing RegSpc, unsigned NumRegs); 53b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng }; 54b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng char ARMExpandPseudo::ID = 0; 55b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng} 56b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 57431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng/// TransferImpOps - Transfer implicit operands on the pseudo instruction to 58431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng/// the instructions created from the expansion. 59431300797b84600fc9b4eb8ca283277d3e0674ebEvan Chengvoid ARMExpandPseudo::TransferImpOps(MachineInstr &OldMI, 60431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder &UseMI, 61431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder &DefMI) { 62431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng const TargetInstrDesc &Desc = OldMI.getDesc(); 63431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng for (unsigned i = Desc.getNumOperands(), e = OldMI.getNumOperands(); 64431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng i != e; ++i) { 65431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng const MachineOperand &MO = OldMI.getOperand(i); 66431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng assert(MO.isReg() && MO.getReg()); 67431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng if (MO.isUse()) 68431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng UseMI.addReg(MO.getReg(), getKillRegState(MO.isKill())); 69431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng else 70431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng DefMI.addReg(MO.getReg(), 71431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng getDefRegState(true) | getDeadRegState(MO.isDead())); 72431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng } 73431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng} 74431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng 7501ba461af7eafc9d181a5c349487691f2e801438Bob Wilson/// ExpandVST - Translate VST pseudo instructions with Q, QQ or QQQQ register 7601ba461af7eafc9d181a5c349487691f2e801438Bob Wilson/// operands to real VST instructions with D register operands. 7701ba461af7eafc9d181a5c349487691f2e801438Bob Wilsonvoid ARMExpandPseudo::ExpandVST(MachineBasicBlock::iterator &MBBI, 7801ba461af7eafc9d181a5c349487691f2e801438Bob Wilson unsigned Opc, bool hasWriteBack, 7901ba461af7eafc9d181a5c349487691f2e801438Bob Wilson NEONRegSpacing RegSpc, unsigned NumRegs) { 80709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MachineInstr &MI = *MBBI; 81709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MachineBasicBlock &MBB = *MI.getParent(); 82709d59255a3100c7d440c93069efa1f726677a27Bob Wilson 83709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MachineInstrBuilder MIB = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(Opc)); 84709d59255a3100c7d440c93069efa1f726677a27Bob Wilson unsigned OpIdx = 0; 85709d59255a3100c7d440c93069efa1f726677a27Bob Wilson if (hasWriteBack) { 86709d59255a3100c7d440c93069efa1f726677a27Bob Wilson bool DstIsDead = MI.getOperand(OpIdx).isDead(); 87709d59255a3100c7d440c93069efa1f726677a27Bob Wilson unsigned DstReg = MI.getOperand(OpIdx++).getReg(); 88709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MIB.addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead)); 89709d59255a3100c7d440c93069efa1f726677a27Bob Wilson } 90709d59255a3100c7d440c93069efa1f726677a27Bob Wilson // Copy the addrmode6 operands. 91709d59255a3100c7d440c93069efa1f726677a27Bob Wilson bool AddrIsKill = MI.getOperand(OpIdx).isKill(); 92709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MIB.addReg(MI.getOperand(OpIdx++).getReg(), getKillRegState(AddrIsKill)); 93709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MIB.addImm(MI.getOperand(OpIdx++).getImm()); 94709d59255a3100c7d440c93069efa1f726677a27Bob Wilson if (hasWriteBack) { 95709d59255a3100c7d440c93069efa1f726677a27Bob Wilson // Copy the am6offset operand. 96709d59255a3100c7d440c93069efa1f726677a27Bob Wilson bool OffsetIsKill = MI.getOperand(OpIdx).isKill(); 97709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MIB.addReg(MI.getOperand(OpIdx++).getReg(), getKillRegState(OffsetIsKill)); 98709d59255a3100c7d440c93069efa1f726677a27Bob Wilson } 99709d59255a3100c7d440c93069efa1f726677a27Bob Wilson 100709d59255a3100c7d440c93069efa1f726677a27Bob Wilson bool SrcIsKill = MI.getOperand(OpIdx).isKill(); 101709d59255a3100c7d440c93069efa1f726677a27Bob Wilson unsigned SrcReg = MI.getOperand(OpIdx).getReg(); 102709d59255a3100c7d440c93069efa1f726677a27Bob Wilson unsigned D0, D1, D2, D3; 103709d59255a3100c7d440c93069efa1f726677a27Bob Wilson if (RegSpc == SingleSpc) { 104709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D0 = TRI->getSubReg(SrcReg, ARM::dsub_0); 105709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D1 = TRI->getSubReg(SrcReg, ARM::dsub_1); 106709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D2 = TRI->getSubReg(SrcReg, ARM::dsub_2); 107709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D3 = TRI->getSubReg(SrcReg, ARM::dsub_3); 108709d59255a3100c7d440c93069efa1f726677a27Bob Wilson } else if (RegSpc == EvenDblSpc) { 109709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D0 = TRI->getSubReg(SrcReg, ARM::dsub_0); 110709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D1 = TRI->getSubReg(SrcReg, ARM::dsub_2); 111709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D2 = TRI->getSubReg(SrcReg, ARM::dsub_4); 112709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D3 = TRI->getSubReg(SrcReg, ARM::dsub_6); 113709d59255a3100c7d440c93069efa1f726677a27Bob Wilson } else { 11401ba461af7eafc9d181a5c349487691f2e801438Bob Wilson assert(RegSpc == OddDblSpc && "unknown register spacing for VST"); 115709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D0 = TRI->getSubReg(SrcReg, ARM::dsub_1); 116709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D1 = TRI->getSubReg(SrcReg, ARM::dsub_3); 117709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D2 = TRI->getSubReg(SrcReg, ARM::dsub_5); 118709d59255a3100c7d440c93069efa1f726677a27Bob Wilson D3 = TRI->getSubReg(SrcReg, ARM::dsub_7); 119709d59255a3100c7d440c93069efa1f726677a27Bob Wilson } 120709d59255a3100c7d440c93069efa1f726677a27Bob Wilson 121709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MIB.addReg(D0, getKillRegState(SrcIsKill)) 122e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson .addReg(D1, getKillRegState(SrcIsKill)); 123e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson if (NumRegs > 2) 124e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson MIB.addReg(D2, getKillRegState(SrcIsKill)); 12501ba461af7eafc9d181a5c349487691f2e801438Bob Wilson if (NumRegs > 3) 12601ba461af7eafc9d181a5c349487691f2e801438Bob Wilson MIB.addReg(D3, getKillRegState(SrcIsKill)); 127709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MIB = AddDefaultPred(MIB); 128709d59255a3100c7d440c93069efa1f726677a27Bob Wilson TransferImpOps(MI, MIB, MIB); 129709d59255a3100c7d440c93069efa1f726677a27Bob Wilson MI.eraseFromParent(); 130709d59255a3100c7d440c93069efa1f726677a27Bob Wilson} 131709d59255a3100c7d440c93069efa1f726677a27Bob Wilson 132b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Chengbool ARMExpandPseudo::ExpandMBB(MachineBasicBlock &MBB) { 133b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng bool Modified = false; 134b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 135b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); 136b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng while (MBBI != E) { 137b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MachineInstr &MI = *MBBI; 1387896c9f436a4eda5ec15e882a7505ba482a2fcd0Chris Lattner MachineBasicBlock::iterator NMBBI = llvm::next(MBBI); 139b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 140709d59255a3100c7d440c93069efa1f726677a27Bob Wilson bool ModifiedOp = true; 141b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng unsigned Opcode = MI.getOpcode(); 142b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng switch (Opcode) { 143709d59255a3100c7d440c93069efa1f726677a27Bob Wilson default: 144709d59255a3100c7d440c93069efa1f726677a27Bob Wilson ModifiedOp = false; 145709d59255a3100c7d440c93069efa1f726677a27Bob Wilson break; 146709d59255a3100c7d440c93069efa1f726677a27Bob Wilson 147b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng case ARM::tLDRpci_pic: 148b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng case ARM::t2LDRpci_pic: { 149b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng unsigned NewLdOpc = (Opcode == ARM::tLDRpci_pic) 150b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng ? ARM::tLDRpci : ARM::t2LDRpci; 151b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng unsigned DstReg = MI.getOperand(0).getReg(); 152431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng bool DstIsDead = MI.getOperand(0).isDead(); 153431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder MIB1 = 154431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), 155431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng TII->get(NewLdOpc), DstReg) 156431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addOperand(MI.getOperand(1))); 157431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng (*MIB1).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 158431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder MIB2 = BuildMI(MBB, MBBI, MI.getDebugLoc(), 159431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng TII->get(ARM::tPICADD)) 160431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead)) 161431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addReg(DstReg) 162431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addOperand(MI.getOperand(2)); 163431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng TransferImpOps(MI, MIB1, MIB2); 164b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MI.eraseFromParent(); 165b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng break; 166b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 167431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng 168b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng case ARM::t2MOVi32imm: { 169431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned PredReg = 0; 170431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng ARMCC::CondCodes Pred = llvm::getInstrPredicate(&MI, PredReg); 171b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng unsigned DstReg = MI.getOperand(0).getReg(); 172431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng bool DstIsDead = MI.getOperand(0).isDead(); 173431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng const MachineOperand &MO = MI.getOperand(1); 174431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng MachineInstrBuilder LO16, HI16; 175431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng 176431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng LO16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVi16), 177431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng DstReg); 178431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng HI16 = BuildMI(MBB, MBBI, MI.getDebugLoc(), TII->get(ARM::t2MOVTi16)) 179431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstIsDead)) 180431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng .addReg(DstReg); 181431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng 182431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng if (MO.isImm()) { 183431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned Imm = MO.getImm(); 184431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned Lo16 = Imm & 0xffff; 185431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned Hi16 = (Imm >> 16) & 0xffff; 186431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng LO16 = LO16.addImm(Lo16); 187431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng HI16 = HI16.addImm(Hi16); 188431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng } else { 189431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng const GlobalValue *GV = MO.getGlobal(); 190431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng unsigned TF = MO.getTargetFlags(); 191431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng LO16 = LO16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_LO16); 192431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng HI16 = HI16.addGlobalAddress(GV, MO.getOffset(), TF | ARMII::MO_HI16); 193b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 194431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng (*LO16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 195431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng (*HI16).setMemRefs(MI.memoperands_begin(), MI.memoperands_end()); 196431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng LO16.addImm(Pred).addReg(PredReg); 197431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng HI16.addImm(Pred).addReg(PredReg); 198431300797b84600fc9b4eb8ca283277d3e0674ebEvan Cheng TransferImpOps(MI, LO16, HI16); 199b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MI.eraseFromParent(); 200d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng break; 201d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng } 202d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng 203d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng case ARM::VMOVQQ: { 204d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng unsigned DstReg = MI.getOperand(0).getReg(); 205d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng bool DstIsDead = MI.getOperand(0).isDead(); 206558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen unsigned EvenDst = TRI->getSubReg(DstReg, ARM::qsub_0); 207558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen unsigned OddDst = TRI->getSubReg(DstReg, ARM::qsub_1); 208d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng unsigned SrcReg = MI.getOperand(1).getReg(); 209d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng bool SrcIsKill = MI.getOperand(1).isKill(); 210558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen unsigned EvenSrc = TRI->getSubReg(SrcReg, ARM::qsub_0); 211558661d2718cf5750907c449d36ff1231924a2d1Jakob Stoklund Olesen unsigned OddSrc = TRI->getSubReg(SrcReg, ARM::qsub_1); 212d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng MachineInstrBuilder Even = 213d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), 214d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng TII->get(ARM::VMOVQ)) 21518f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach .addReg(EvenDst, 21618f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach getDefRegState(true) | getDeadRegState(DstIsDead)) 21718f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach .addReg(EvenSrc, getKillRegState(SrcIsKill))); 218d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng MachineInstrBuilder Odd = 219d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng AddDefaultPred(BuildMI(MBB, MBBI, MI.getDebugLoc(), 220d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng TII->get(ARM::VMOVQ)) 22118f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach .addReg(OddDst, 22218f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach getDefRegState(true) | getDeadRegState(DstIsDead)) 22318f30e6f5e80787808fe1455742452a5210afe07Jim Grosbach .addReg(OddSrc, getKillRegState(SrcIsKill))); 224d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng TransferImpOps(MI, Even, Odd); 225d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng MI.eraseFromParent(); 226b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 227709d59255a3100c7d440c93069efa1f726677a27Bob Wilson 228e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST1q8Pseudo: 229e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST1q8, false, SingleSpc, 2); break; 230e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST1q16Pseudo: 231e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST1q16, false, SingleSpc, 2); break; 232e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST1q32Pseudo: 233e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST1q32, false, SingleSpc, 2); break; 234e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST1q64Pseudo: 235e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST1q64, false, SingleSpc, 2); break; 236e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST1q8Pseudo_UPD: 237e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST1q8_UPD, true, SingleSpc, 2); break; 238e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST1q16Pseudo_UPD: 239e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST1q16_UPD, true, SingleSpc, 2); break; 240e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST1q32Pseudo_UPD: 241e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST1q32_UPD, true, SingleSpc, 2); break; 242e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST1q64Pseudo_UPD: 243e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST1q64_UPD, true, SingleSpc, 2); break; 244e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson 245e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2d8Pseudo: 246e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2d8, false, SingleSpc, 2); break; 247e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2d16Pseudo: 248e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2d16, false, SingleSpc, 2); break; 249e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2d32Pseudo: 250e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2d32, false, SingleSpc, 2); break; 251e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2q8Pseudo: 252e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2q8, false, SingleSpc, 4); break; 253e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2q16Pseudo: 254e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2q16, false, SingleSpc, 4); break; 255e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2q32Pseudo: 256e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2q32, false, SingleSpc, 4); break; 257e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2d8Pseudo_UPD: 258e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2d8_UPD, true, SingleSpc, 2); break; 259e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2d16Pseudo_UPD: 260e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2d16_UPD, true, SingleSpc, 2); break; 261e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2d32Pseudo_UPD: 262e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2d32_UPD, true, SingleSpc, 2); break; 263e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2q8Pseudo_UPD: 264e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2q8_UPD, true, SingleSpc, 4); break; 265e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2q16Pseudo_UPD: 266e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2q16_UPD, true, SingleSpc, 4); break; 267e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson case ARM::VST2q32Pseudo_UPD: 268e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson ExpandVST(MBBI, ARM::VST2q32_UPD, true, SingleSpc, 4); break; 269e5ce4f68c786696a96acf1f1aa5431652abb6ce7Bob Wilson 27001ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3d8Pseudo: 27101ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3d8, false, SingleSpc, 3); break; 27201ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3d16Pseudo: 27301ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3d16, false, SingleSpc, 3); break; 27401ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3d32Pseudo: 27501ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3d32, false, SingleSpc, 3); break; 27601ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST1d64TPseudo: 27701ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST1d64T, false, SingleSpc, 3); break; 27801ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3d8Pseudo_UPD: 27901ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3d8_UPD, true, SingleSpc, 3); break; 28001ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3d16Pseudo_UPD: 28101ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3d16_UPD, true, SingleSpc, 3); break; 28201ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3d32Pseudo_UPD: 28301ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3d32_UPD, true, SingleSpc, 3); break; 28401ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST1d64TPseudo_UPD: 28501ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST1d64T_UPD, true, SingleSpc, 3); break; 28601ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3q8Pseudo_UPD: 28701ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3q8_UPD, true, EvenDblSpc, 3); break; 28801ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3q16Pseudo_UPD: 28901ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3q16_UPD, true, EvenDblSpc, 3); break; 29001ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3q32Pseudo_UPD: 29101ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3q32_UPD, true, EvenDblSpc, 3); break; 29201ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3q8oddPseudo_UPD: 29301ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3q8_UPD, true, OddDblSpc, 3); break; 29401ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3q16oddPseudo_UPD: 29501ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3q16_UPD, true, OddDblSpc, 3); break; 29601ba461af7eafc9d181a5c349487691f2e801438Bob Wilson case ARM::VST3q32oddPseudo_UPD: 29701ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST3q32_UPD, true, OddDblSpc, 3); break; 29801ba461af7eafc9d181a5c349487691f2e801438Bob Wilson 299709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4d8Pseudo: 30001ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4d8, false, SingleSpc, 4); break; 301709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4d16Pseudo: 30201ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4d16, false, SingleSpc, 4); break; 303709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4d32Pseudo: 30401ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4d32, false, SingleSpc, 4); break; 30570e48b23a3455e4689ee24cec4eb153d67223e86Bob Wilson case ARM::VST1d64QPseudo: 30601ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST1d64Q, false, SingleSpc, 4); break; 307709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4d8Pseudo_UPD: 30801ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4d8_UPD, true, SingleSpc, 4); break; 309709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4d16Pseudo_UPD: 31001ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4d16_UPD, true, SingleSpc, 4); break; 311709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4d32Pseudo_UPD: 31201ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4d32_UPD, true, SingleSpc, 4); break; 31370e48b23a3455e4689ee24cec4eb153d67223e86Bob Wilson case ARM::VST1d64QPseudo_UPD: 31401ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST1d64Q_UPD, true, SingleSpc, 4); break; 315709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4q8Pseudo_UPD: 31601ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4q8_UPD, true, EvenDblSpc, 4); break; 317709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4q16Pseudo_UPD: 31801ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4q16_UPD, true, EvenDblSpc, 4); break; 319709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4q32Pseudo_UPD: 32001ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4q32_UPD, true, EvenDblSpc, 4); break; 321709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4q8oddPseudo_UPD: 32201ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4q8_UPD, true, OddDblSpc, 4); break; 323709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4q16oddPseudo_UPD: 32401ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4q16_UPD, true, OddDblSpc, 4); break; 325709d59255a3100c7d440c93069efa1f726677a27Bob Wilson case ARM::VST4q32oddPseudo_UPD: 32601ba461af7eafc9d181a5c349487691f2e801438Bob Wilson ExpandVST(MBBI, ARM::VST4q32_UPD, true, OddDblSpc, 4); break; 327b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 328709d59255a3100c7d440c93069efa1f726677a27Bob Wilson 329709d59255a3100c7d440c93069efa1f726677a27Bob Wilson if (ModifiedOp) 330709d59255a3100c7d440c93069efa1f726677a27Bob Wilson Modified = true; 331b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng MBBI = NMBBI; 332b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng } 333b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 334b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng return Modified; 335b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng} 336b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 337b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Chengbool ARMExpandPseudo::runOnMachineFunction(MachineFunction &MF) { 338b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng TII = MF.getTarget().getInstrInfo(); 339d929f7773812535271ae6969331f8164c1f7f3b2Evan Cheng TRI = MF.getTarget().getRegisterInfo(); 340b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 341b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng bool Modified = false; 342b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng for (MachineFunction::iterator MFI = MF.begin(), E = MF.end(); MFI != E; 343b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng ++MFI) 344b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng Modified |= ExpandMBB(*MFI); 345b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng return Modified; 346b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng} 347b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng 348b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng/// createARMExpandPseudoPass - returns an instance of the pseudo instruction 349b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng/// expansion pass. 350b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan ChengFunctionPass *llvm::createARMExpandPseudoPass() { 351b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng return new ARMExpandPseudo(); 352b9803a8fa65f043c96612fa9c5aeeee12739db2bEvan Cheng} 353