diff options
Diffstat (limited to 'llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp')
-rw-r--r-- | llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp | 56 |
1 files changed, 23 insertions, 33 deletions
diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp index 8313d909df2..2c384b8addb 100644 --- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -507,23 +507,13 @@ getUnderlyingObjects(const MachineInstr &MI, // Replace Branch with the compact branch instruction. Iter Filler::replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch, DebugLoc DL) { - const MipsInstrInfo *TII = - MBB.getParent()->getSubtarget<MipsSubtarget>().getInstrInfo(); - - unsigned NewOpcode = - (((unsigned) Branch->getOpcode()) == Mips::BEQ) ? Mips::BEQZC_MM - : Mips::BNEZC_MM; - - const MCInstrDesc &NewDesc = TII->get(NewOpcode); - MachineInstrBuilder MIB = BuildMI(MBB, Branch, DL, NewDesc); - - MIB.addReg(Branch->getOperand(0).getReg()); - MIB.addMBB(Branch->getOperand(2).getMBB()); + const MipsSubtarget &STI = MBB.getParent()->getSubtarget<MipsSubtarget>(); + const MipsInstrInfo *TII = STI.getInstrInfo(); - Iter tmpIter = Branch; - Branch = std::prev(Branch); - MBB.erase(tmpIter); + unsigned NewOpcode = TII->getEquivalentCompactForm(Branch); + Branch = TII->genInstrWithNewOpc(NewOpcode, Branch); + std::next(Branch)->eraseFromParent(); return Branch; } @@ -611,27 +601,27 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { // If instruction is BEQ or BNE with one ZERO register, then instead of // adding NOP replace this instruction with the corresponding compact // branch instruction, i.e. BEQZC or BNEZC. - unsigned Opcode = I->getOpcode(); if (InMicroMipsMode) { - switch (Opcode) { - case Mips::BEQ: - case Mips::BNE: - if (((unsigned) I->getOperand(1).getReg()) == Mips::ZERO) { - I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); - continue; - } - break; - case Mips::JR: - case Mips::PseudoReturn: - case Mips::PseudoIndirectBranch: - // For microMIPS the PseudoReturn and PseudoIndirectBranch are allways - // expanded to JR_MM, so they can be replaced with JRC16_MM. - I = replaceWithCompactJump(MBB, I, I->getDebugLoc()); - continue; - default: - break; + if (TII->getEquivalentCompactForm(I)) { + I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); + continue; + } + + if (I->isIndirectBranch() || I->isReturn()) { + // For microMIPS the PseudoReturn and PseudoIndirectBranch are always + // expanded to JR_MM, so they can be replaced with JRC16_MM. + I = replaceWithCompactJump(MBB, I, I->getDebugLoc()); + continue; } } + + // For MIPSR6 attempt to produce the corresponding compact (no delay slot) + // form of the branch. This should save putting in a NOP. + if ((STI.hasMips32r6()) && TII->getEquivalentCompactForm(I)) { + I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); + continue; + } + // Bundle the NOP to the instruction with the delay slot. BuildMI(MBB, std::next(I), I->getDebugLoc(), TII->get(Mips::NOP)); MIBundleBuilder(MBB, I, std::next(I, 2)); |