summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp53
-rw-r--r--llvm/test/CodeGen/Mips/longbranch.ll3
-rw-r--r--llvm/test/CodeGen/Mips/micromips-compact-jump.ll11
-rw-r--r--llvm/test/CodeGen/Mips/micromips-delay-slot-jr.ll6
4 files changed, 57 insertions, 16 deletions
diff --git a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp b/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
index 8c2040d5c16..ac03c0bd3dd 100644
--- a/llvm/lib/Target/Mips/MipsDelaySlotFiller.cpp
+++ b/llvm/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<MipsSubtarget>().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/llvm/test/CodeGen/Mips/longbranch.ll b/llvm/test/CodeGen/Mips/longbranch.ll
index 821ced8e7b8..f61b250491e 100644
--- a/llvm/test/CodeGen/Mips/longbranch.ll
+++ b/llvm/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/llvm/test/CodeGen/Mips/micromips-compact-jump.ll b/llvm/test/CodeGen/Mips/micromips-compact-jump.ll
new file mode 100644
index 00000000000..70cff84e967
--- /dev/null
+++ b/llvm/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/llvm/test/CodeGen/Mips/micromips-delay-slot-jr.ll b/llvm/test/CodeGen/Mips/micromips-delay-slot-jr.ll
index df593b35e2a..09a98c2a7d1 100644
--- a/llvm/test/CodeGen/Mips/micromips-delay-slot-jr.ll
+++ b/llvm/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
OpenPOWER on IntegriCloud