Index: llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp =================================================================== --- llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp +++ llvm/trunk/lib/Target/Mips/MipsDelaySlotFiller.cpp @@ -199,6 +199,9 @@ 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 @@ 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 @@ // 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; Index: llvm/trunk/test/CodeGen/Mips/longbranch.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/longbranch.ll +++ llvm/trunk/test/CodeGen/Mips/longbranch.ll @@ -126,8 +126,7 @@ ; 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 Index: llvm/trunk/test/CodeGen/Mips/micromips-compact-jump.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/micromips-compact-jump.ll +++ llvm/trunk/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 Index: llvm/trunk/test/CodeGen/Mips/micromips-delay-slot-jr.ll =================================================================== --- llvm/trunk/test/CodeGen/Mips/micromips-delay-slot-jr.ll +++ llvm/trunk/test/CodeGen/Mips/micromips-delay-slot-jr.ll @@ -29,8 +29,7 @@ !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 @@ } ; CHECK: spooky: -; CHECK: jr $ra -; CHECK-NEXT: nop +; CHECK: jrc $ra