diff options
Diffstat (limited to 'lib/Target/ARM/Thumb2ITBlockPass.cpp')
-rw-r--r-- | lib/Target/ARM/Thumb2ITBlockPass.cpp | 37 |
1 files changed, 31 insertions, 6 deletions
diff --git a/lib/Target/ARM/Thumb2ITBlockPass.cpp b/lib/Target/ARM/Thumb2ITBlockPass.cpp index e74a526afa..a06ee8eca8 100644 --- a/lib/Target/ARM/Thumb2ITBlockPass.cpp +++ b/lib/Target/ARM/Thumb2ITBlockPass.cpp @@ -40,12 +40,11 @@ namespace { char Thumb2ITBlockPass::ID = 0; } -static ARMCC::CondCodes getPredicate(const MachineInstr *MI, - const Thumb2InstrInfo *TII) { +static ARMCC::CondCodes getPredicate(const MachineInstr *MI, unsigned &PredReg){ unsigned Opc = MI->getOpcode(); if (Opc == ARM::tBcc || Opc == ARM::t2Bcc) return ARMCC::AL; - return TII->getPredicate(MI); + return llvm::getInstrPredicate(MI, PredReg); } bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) { @@ -54,14 +53,39 @@ bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) { MachineBasicBlock::iterator MBBI = MBB.begin(), E = MBB.end(); while (MBBI != E) { MachineInstr *MI = &*MBBI; - ARMCC::CondCodes CC = getPredicate(MI, TII); + DebugLoc dl = MI->getDebugLoc(); + unsigned PredReg = 0; + ARMCC::CondCodes CC = getPredicate(MI, PredReg); + + // Splitting t2MOVi32imm into a pair of t2MOVi16 + t2MOVTi16 here. + // The only reason it was a single instruction was so it could be + // re-materialized. We want to split it before this and the thumb2 + // size reduction pass to make sure the IT mask is correct and expose + // width reduction opportunities. It doesn't make sense to do this in a + // separate pass so here it is. + if (MI->getOpcode() == ARM::t2MOVi32imm) { + unsigned DstReg = MI->getOperand(0).getReg(); + bool DstDead = MI->getOperand(0).isDead(); // Is this possible? + unsigned Imm = MI->getOperand(1).getImm(); + unsigned Lo16 = Imm & 0xffff; + unsigned Hi16 = (Imm >> 16) & 0xffff; + BuildMI(MBB, MBBI, dl, TII->get(ARM::t2MOVi16), DstReg) + .addImm(Lo16).addImm(CC).addReg(PredReg); + BuildMI(MBB, MBBI, dl, TII->get(ARM::t2MOVTi16)) + .addReg(DstReg, getDefRegState(true) | getDeadRegState(DstDead)) + .addReg(DstReg).addImm(Hi16).addImm(CC).addReg(PredReg); + --MBBI; + --MBBI; + MI->eraseFromParent(); + continue; + } + if (CC == ARMCC::AL) { ++MBBI; continue; } // Insert an IT instruction. - DebugLoc dl = MI->getDebugLoc(); MachineInstrBuilder MIB = BuildMI(MBB, MBBI, dl, TII->get(ARM::t2IT)) .addImm(CC); ++MBBI; @@ -70,7 +94,8 @@ bool Thumb2ITBlockPass::InsertITBlocks(MachineBasicBlock &MBB) { ARMCC::CondCodes OCC = ARMCC::getOppositeCondition(CC); unsigned Mask = 0, Pos = 3; while (MBBI != E && Pos) { - ARMCC::CondCodes NCC = getPredicate(&*MBBI, TII); + unsigned Dummy = 0; + ARMCC::CondCodes NCC = getPredicate(&*MBBI, Dummy); if (NCC == OCC) { Mask |= (1 << Pos); } else if (NCC != CC) |