[mips][mips64r6] Use JALR for indirect branches instead of JR (which is not available...
authorDaniel Sanders <daniel.sanders@imgtec.com>
Wed, 9 Jul 2014 10:21:59 +0000 (10:21 +0000)
committerDaniel Sanders <daniel.sanders@imgtec.com>
Wed, 9 Jul 2014 10:21:59 +0000 (10:21 +0000)
Summary:
This completes the change to use JALR instead of JR on MIPS32r6/MIPS64r6.

Reviewers: jkolek, vmedic, zoran.jovanovic, dsanders

Reviewed By: dsanders

Subscribers: llvm-commits

Differential Revision: http://reviews.llvm.org/D4269

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@212605 91177308-0d34-0410-b5e6-96231b3b80d8

lib/Target/Mips/Mips16InstrInfo.td
lib/Target/Mips/Mips64InstrInfo.td
lib/Target/Mips/MipsAsmPrinter.cpp
lib/Target/Mips/MipsAsmPrinter.h
lib/Target/Mips/MipsInstrInfo.td
test/CodeGen/Mips/llvm-ir/call.ll
test/CodeGen/Mips/llvm-ir/indirectbr.ll

index 11166c45a880eb4b9031916722b4e866a2ecf070..5e4eebb62c1248b0198b71c7a1d3451c0f69ecc9 100644 (file)
@@ -1370,9 +1370,11 @@ def : Mips16Pat<(MipsJmpLink (i32 texternalsym:$dst)),
                 (Jal16 texternalsym:$dst)>;
 
 // Indirect branch
-def: Mips16Pat<
-  (brind CPU16Regs:$rs),
-  (JrcRx16 CPU16Regs:$rs)>;
+def: Mips16Pat<(brind CPU16Regs:$rs), (JrcRx16 CPU16Regs:$rs)> {
+  // Ensure that the addition of MIPS32r6/MIPS64r6 support does not change
+  // MIPS16's behaviour.
+  let AddedComplexity = 1;
+}
 
 // Jump and Link (Call)
 let isCall=1, hasDelaySlot=0 in
index 3b8f9e3a21e5a201df1d61f96c0877b92d1e0940..f0b6814e37cc47e37e0bd23e1a9798bcc3ed9310 100644 (file)
@@ -174,19 +174,20 @@ def SCD : SCBase<"scd", GPR64Opnd>, LW_FM<0x3c>, ISA_MIPS3_NOT_32R6_64R6;
 
 /// Jump and Branch Instructions
 let isCodeGenOnly = 1 in {
-def JR64   : IndirectBranch<"jr", GPR64Opnd>, MTLO_FM<8>;
-def BEQ64  : CBranch<"beq", brtarget, seteq, GPR64Opnd>, BEQ_FM<4>;
-def BNE64  : CBranch<"bne", brtarget, setne, GPR64Opnd>, BEQ_FM<5>;
-def BGEZ64 : CBranchZero<"bgez", brtarget, setge, GPR64Opnd>, BGEZ_FM<1, 1>;
-def BGTZ64 : CBranchZero<"bgtz", brtarget, setgt, GPR64Opnd>, BGEZ_FM<7, 0>;
-def BLEZ64 : CBranchZero<"blez", brtarget, setle, GPR64Opnd>, BGEZ_FM<6, 0>;
-def BLTZ64 : CBranchZero<"bltz", brtarget, setlt, GPR64Opnd>, BGEZ_FM<1, 0>;
-def JALR64 : JumpLinkReg<"jalr", GPR64Opnd>, JALR_FM;
-def JALR64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR, RA, GPR32Opnd>;
-def TAILCALL64_R : TailCallReg<GPR64Opnd, JR, GPR32Opnd>;
+  def JR64   : IndirectBranch<"jr", GPR64Opnd>, MTLO_FM<8>;
+  def BEQ64  : CBranch<"beq", brtarget, seteq, GPR64Opnd>, BEQ_FM<4>;
+  def BNE64  : CBranch<"bne", brtarget, setne, GPR64Opnd>, BEQ_FM<5>;
+  def BGEZ64 : CBranchZero<"bgez", brtarget, setge, GPR64Opnd>, BGEZ_FM<1, 1>;
+  def BGTZ64 : CBranchZero<"bgtz", brtarget, setgt, GPR64Opnd>, BGEZ_FM<7, 0>;
+  def BLEZ64 : CBranchZero<"blez", brtarget, setle, GPR64Opnd>, BGEZ_FM<6, 0>;
+  def BLTZ64 : CBranchZero<"bltz", brtarget, setlt, GPR64Opnd>, BGEZ_FM<1, 0>;
+  def JALR64 : JumpLinkReg<"jalr", GPR64Opnd>, JALR_FM;
+  def JALR64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR, RA, GPR32Opnd>;
+  def TAILCALL64_R : TailCallReg<GPR64Opnd, JR, GPR32Opnd>;
 }
 
 def PseudoReturn64 : PseudoReturnBase<GPR64Opnd>;
+def PseudoIndirectBranch64 : PseudoIndirectBranchBase<GPR64Opnd>;
 
 /// Multiply and Divide Instructions.
 def DMULT  : Mult<"dmult", II_DMULT, GPR64Opnd, [HI0_64, LO0_64]>,
index 60ec0e2eca53238ae023b13402df55cdf4c43fac..4d4fcd96a4fedd62e83a654491268ccf64078289 100644 (file)
@@ -91,10 +91,10 @@ bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
 
 #include "MipsGenMCPseudoLowering.inc"
 
-void MipsAsmPrinter::emitPseudoReturn(MCStreamer &OutStreamer,
-                                      const MachineInstr *MI) {
-  // Lower PseudoReturn to JR, JR_MM, JALR, or JALR64 as appropriate for the
-  // target
+// Lower PseudoReturn/PseudoIndirectBranch/PseudoIndirectBranch64 to JR, JR_MM,
+// JALR, or JALR64 as appropriate for the target
+void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
+                                              const MachineInstr *MI) {
   bool HasLinkReg = false;
   MCInst TmpInst0;
 
@@ -181,8 +181,10 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
       continue;
 
     if (I->getOpcode() == Mips::PseudoReturn ||
-        I->getOpcode() == Mips::PseudoReturn64) {
-      emitPseudoReturn(OutStreamer, &*I);
+        I->getOpcode() == Mips::PseudoReturn64 ||
+        I->getOpcode() == Mips::PseudoIndirectBranch ||
+        I->getOpcode() == Mips::PseudoIndirectBranch64) {
+      emitPseudoIndirectBranch(OutStreamer, &*I);
       continue;
     }
 
index b0f623305924cfe46232701606e3d4b34dc6c900..967aa0b16416fac30028035c484d3aa3b1520f0d 100644 (file)
@@ -40,7 +40,11 @@ private:
   bool emitPseudoExpansionLowering(MCStreamer &OutStreamer,
                                    const MachineInstr *MI);
 
-  void emitPseudoReturn(MCStreamer &OutStreamer, const MachineInstr *MI);
+  // Emit PseudoReturn, PseudoReturn64, PseudoIndirectBranch,
+  // and PseudoIndirectBranch64 as a JR, JR_MM, JALR, or JALR64 as appropriate
+  // for the target.
+  void emitPseudoIndirectBranch(MCStreamer &OutStreamer,
+                                const MachineInstr *MI);
 
   // lowerOperand - Convert a MachineOperand into the equivalent MCOperand.
   bool lowerOperand(const MachineOperand &MO, MCOperand &MCOp);
index 895cf4db582a459bf4872e39525a0414b9b24f69..d3dd87836c01d66847d1da17259ebfc1786299bf 100644 (file)
@@ -743,8 +743,7 @@ class JumpFR<string opstr, RegisterOperand RO,
          FrmR, opstr>;
 
 // Indirect branch
-class IndirectBranch<string opstr, RegisterOperand RO> :
-      JumpFR<opstr, RO, brind> {
+class IndirectBranch<string opstr, RegisterOperand RO> : JumpFR<opstr, RO> {
   let isBranch = 1;
   let isIndirectBranch = 1;
 }
@@ -1221,9 +1220,23 @@ def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
 def TAILCALL : TailCall<J>;
 def TAILCALL_R : TailCallReg<GPR32Opnd, JR>;
 
-// Return instruction
-// RetRA is expanded into this after register allocation and then MipsAsmPrinter
-// expands this into JR, or JALR depending on the ISA.
+// Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
+// then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
+class PseudoIndirectBranchBase<RegisterOperand RO> :
+    MipsPseudo<(outs), (ins RO:$rs), [(brind RO:$rs)], IIBranch> {
+  let isTerminator=1;
+  let isBarrier=1;
+  let hasDelaySlot = 1;
+  let isBranch = 1;
+  let isIndirectBranch = 1;
+}
+
+def PseudoIndirectBranch : PseudoIndirectBranchBase<GPR32Opnd>;
+
+// Return instructions are matched as a RetRA instruction, then ar expanded
+// into PseudoReturn/PseudoReturn64 after register allocation. Finally,
+// MipsAsmPrinter expands this into JR, JR64, JALR, or JALR64 depending on the
+// ISA.
 class PseudoReturnBase<RegisterOperand RO> : MipsPseudo<(outs), (ins RO:$rs),
                                                         [], IIBranch> {
   let isTerminator = 1;
index 0752fc7ac7dbd448f41c0b7f9e81d0c514947908..4cbf43cae28e4e1b6fafb6d0c67d63dd53a84485 100644 (file)
@@ -3,8 +3,11 @@
 ; FIXME: We should remove the need for -enable-mips-tail-calls
 ; RUN: llc -march=mips   -mcpu=mips32   -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
 ; RUN: llc -march=mips   -mcpu=mips32r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
+; RUN: llc -march=mips   -mcpu=mips32r6 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=O32
 ; RUN: llc -march=mips64 -mcpu=mips4    -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
 ; RUN: llc -march=mips64 -mcpu=mips64   -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
+; RUN: llc -march=mips64 -mcpu=mips64r2 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
+; RUN: llc -march=mips64 -mcpu=mips64r6 -enable-mips-tail-calls < %s | FileCheck %s -check-prefix=ALL -check-prefix=N64
 
 declare void @extern_void_void()
 declare i32 @extern_i32_void()
@@ -63,7 +66,8 @@ define void @musttail_call_void_void() {
 
 ; N64:           ld $[[TGT:[0-9]+]], %call16(extern_void_void)($gp)
 
-; ALL:           jr $[[TGT]]
+; NOT-R6:        jr $[[TGT]]
+; R6:            r6.jr $[[TGT]]
 
   musttail call void @extern_void_void()
   ret void
@@ -76,7 +80,8 @@ define i32 @musttail_call_i32_void() {
 
 ; N64:           ld $[[TGT:[0-9]+]], %call16(extern_i32_void)($gp)
 
-; ALL:           jr $[[TGT]]
+; NOT-R6:        jr $[[TGT]]
+; R6:            r6.jr $[[TGT]]
 
   %1 = musttail call i32 @extern_i32_void()
   ret i32 %1
@@ -89,7 +94,8 @@ define float @musttail_call_float_void() {
 
 ; N64:           ld $[[TGT:[0-9]+]], %call16(extern_float_void)($gp)
 
-; ALL:           jr $[[TGT]]
+; NOT-R6:        jr $[[TGT]]
+; R6:            r6.jr $[[TGT]]
 
   %1 = musttail call float @extern_float_void()
   ret float %1
index 49fbb004871dd414c54e0a65ecb4bdceca403934..d8fd78774553c3c7efec5646866a942b39551dac 100644 (file)
@@ -1,19 +1,26 @@
 ; Test all important variants of the unconditional 'br' instruction.
 
-; RUN: llc -march=mips   -mcpu=mips32   < %s | FileCheck %s -check-prefix=ALL
-; RUN: llc -march=mips   -mcpu=mips32r2 < %s | FileCheck %s -check-prefix=ALL
-; RUN: llc -march=mips64 -mcpu=mips4    < %s | FileCheck %s -check-prefix=ALL
-; RUN: llc -march=mips64 -mcpu=mips64   < %s | FileCheck %s -check-prefix=ALL
-; RUN: llc -march=mips64 -mcpu=mips64r2 < %s | FileCheck %s -check-prefix=ALL
+; RUN: llc -march=mips   -mcpu=mips32   -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6
+; RUN: llc -march=mips   -mcpu=mips32r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6
+; RUN: llc -march=mips   -mcpu=mips32r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=R6
+; RUN: llc -march=mips64 -mcpu=mips4    -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6
+; RUN: llc -march=mips64 -mcpu=mips64   -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6
+; RUN: llc -march=mips64 -mcpu=mips64r2 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=NOT-R6
+; RUN: llc -march=mips64 -mcpu=mips64r6 -asm-show-inst < %s | FileCheck %s -check-prefix=ALL -check-prefix=R6
 
 define i32 @br(i8 *%addr) {
 ; ALL-LABEL: br:
-; ALL:           jr $4
+; NOT-R6:        jr $4 # <MCInst #{{[0-9]+}} JR
+; R6:            jr $4 # <MCInst #{{[0-9]+}} JALR
+
 ; ALL: $BB0_1: # %L1
-; ALL:           jr $ra
+; NOT-R6:        jr $ra # <MCInst #{{[0-9]+}} JR
+; R6:            jr $ra # <MCInst #{{[0-9]+}} JALR
 ; ALL:           addiu $2, $zero, 0
+
 ; ALL: $BB0_2: # %L2
-; ALL:           jr $ra
+; NOT-R6:        jr $ra # <MCInst #{{[0-9]+}} JR
+; R6:            jr $ra # <MCInst #{{[0-9]+}} JALR
 ; ALL:           addiu $2, $zero, 1
 
 entry: