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