diff --git a/lib/Target/Mips/MipsDelaySlotFiller.cpp b/lib/Target/Mips/MipsDelaySlotFiller.cpp index 8c2040d5c16..ac03c0bd3dd 100644 --- a/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ b/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -199,6 +199,9 @@ namespace { Iter replaceWithCompactBranch(MachineBasicBlock &MBB, Iter Branch, DebugLoc DL); + Iter replaceWithCompactJump(MachineBasicBlock &MBB, + Iter Jump, DebugLoc DL); + /// This function checks if it is valid to move Candidate to the delay slot /// and returns true if it isn't. It also updates memory and register /// dependence information. @@ -515,6 +518,24 @@ Iter Filler::replaceWithCompactBranch(MachineBasicBlock &MBB, return Branch; } +// Replace Jumps with the compact jump instruction. +Iter Filler::replaceWithCompactJump(MachineBasicBlock &MBB, + Iter Jump, DebugLoc DL) { + const MipsInstrInfo *TII = + MBB.getParent()->getSubtarget().getInstrInfo(); + + const MCInstrDesc &NewDesc = TII->get(Mips::JRC16_MM); + MachineInstrBuilder MIB = BuildMI(MBB, Jump, DL, NewDesc); + + MIB.addReg(Jump->getOperand(0).getReg()); + + Iter tmpIter = Jump; + Jump = std::prev(Jump); + MBB.erase(tmpIter); + + return Jump; +} + // For given opcode returns opcode of corresponding instruction with short // delay slot. static int getEquivalentCallShort(int Opcode) { @@ -582,17 +603,29 @@ bool Filler::runOnMachineBasicBlock(MachineBasicBlock &MBB) { // adding NOP replace this instruction with the corresponding compact // branch instruction, i.e. BEQZC or BNEZC. unsigned Opcode = I->getOpcode(); - if (InMicroMipsMode && - (Opcode == Mips::BEQ || Opcode == Mips::BNE) && - ((unsigned) I->getOperand(1).getReg()) == Mips::ZERO) { - - I = replaceWithCompactBranch(MBB, I, I->getDebugLoc()); - - } else { - // 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)); + 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; + } } + // 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)); } return Changed; diff --git a/test/CodeGen/Mips/longbranch.ll b/test/CodeGen/Mips/longbranch.ll index 821ced8e7b8..f61b250491e 100644 --- a/test/CodeGen/Mips/longbranch.ll +++ b/test/CodeGen/Mips/longbranch.ll @@ -126,8 +126,7 @@ end: ; MICROMIPS: li16 $[[R2:[0-9]+]], 1 ; MICROMIPS: sw16 $[[R2]], 0($[[R1]]) ; MICROMIPS: $[[BB2]]: -; MICROMIPS: jr $ra -; MICROMIPS: nop +; MICROMIPS: jrc $ra ; Check the NaCl version. Check that sp change is not in the branch delay slot diff --git a/test/CodeGen/Mips/micromips-compact-jump.ll b/test/CodeGen/Mips/micromips-compact-jump.ll new file mode 100644 index 00000000000..70cff84e967 --- /dev/null +++ b/test/CodeGen/Mips/micromips-compact-jump.ll @@ -0,0 +1,11 @@ +; RUN: llc -march=mipsel -mcpu=mips32r2 -mattr=+micromips \ +; RUN: -disable-mips-delay-filler -O3 < %s | FileCheck %s + +define i32 @foo(i32 signext %a) #0 { +entry: + ret i32 0 +} + +declare i32 @bar(i32 signext) #1 + +; CHECK: jrc diff --git a/test/CodeGen/Mips/micromips-delay-slot-jr.ll b/test/CodeGen/Mips/micromips-delay-slot-jr.ll index df593b35e2a..09a98c2a7d1 100644 --- a/test/CodeGen/Mips/micromips-delay-slot-jr.ll +++ b/test/CodeGen/Mips/micromips-delay-slot-jr.ll @@ -29,8 +29,7 @@ declare i32 @puts(i8* nocapture readonly) #1 !3 = !{!"omnipotent char", !4, i64 0} !4 = !{!"Simple C/C++ TBAA"} -; CHECK: jr -; CHECK-NEXT: nop +; CHECK: jrc %struct.foostruct = type { [3 x float] } %struct.barstruct = type { %struct.foostruct, float } @@ -43,6 +42,5 @@ define float* @spooky(i32 signext %i) #0 { } ; CHECK: spooky: -; CHECK: jr $ra -; CHECK-NEXT: nop +; CHECK: jrc $ra