mirror of
https://github.com/RPCS3/llvm-mirror.git
synced 2024-11-25 20:23:11 +01:00
[mips] Correct tail call encoding for MIPSR6
r277708 enabled tails calls for MIPS but used the 'jr' instruction when the jump target was held in a register. For MIPSR6, 'jalr $zero, $reg' should have been used. Additionally, add missing patterns for external and global symbols for tail calls. Reviewers: dsanders, vkalintiris Differential Review: https://reviews.llvm.org/D23301 llvm-svn: 279064
This commit is contained in:
parent
0d8cfe4017
commit
578fdb3ee7
@ -1772,3 +1772,5 @@ let AddedComplexity = 41 in {
|
||||
def : LoadRegImmPat<LDC1_D64_MMR6, f64, load>, FGR_64, ISA_MICROMIPS32R6;
|
||||
def : StoreRegImmPat<SDC1_D64_MMR6, f64>, FGR_64, ISA_MICROMIPS32R6;
|
||||
}
|
||||
|
||||
def TAILCALL_MMR6 : TailCall<BC_MMR6, brtarget26_mm>, ISA_MICROMIPS32R6;
|
||||
|
@ -471,18 +471,6 @@ class JumpRegCMM16<string opstr, RegisterOperand RO> :
|
||||
let isIndirectBranch = 1;
|
||||
}
|
||||
|
||||
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
|
||||
hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
|
||||
class TailCall_MM<Instruction JumpInst> :
|
||||
PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
|
||||
PseudoInstExpansion<(JumpInst jmptarget_mm:$target)>;
|
||||
|
||||
class TailCallReg_MM<RegisterOperand RO, Instruction JRInst,
|
||||
RegisterOperand ResRO = RO> :
|
||||
PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
|
||||
PseudoInstExpansion<(JRInst ResRO:$rs)>;
|
||||
}
|
||||
|
||||
// Break16 and Sdbbp16
|
||||
class BrkSdbbp16MM<string opstr> :
|
||||
MicroMipsInst16<(outs), (ins uimm4:$code_),
|
||||
@ -989,11 +977,7 @@ let DecoderNamespace = "MicroMips", Predicates = [InMicroMips] in {
|
||||
def PREFX_MM : PrefetchIndexed<"prefx">, POOL32F_PREFX_FM_MM<0x15, 0x1A0>;
|
||||
}
|
||||
|
||||
let AdditionalPredicates = [InMicroMips] in {
|
||||
def TAILCALL_MM : TailCall_MM<J_MM>, ISA_MIPS1_NOT_32R6_64R6;
|
||||
def TAILCALLREG_MM : TailCallReg_MM<GPR32Opnd, JR_MM>,
|
||||
ISA_MIPS1_NOT_32R6_64R6;
|
||||
}
|
||||
def TAILCALL_MM : TailCall<J_MM, jmptarget_mm>, ISA_MIPS1_NOT_32R6_64R6;
|
||||
|
||||
let DecoderNamespace = "MicroMips" in {
|
||||
def RDHWR_MM : MMRel, R6MMR6Rel, ReadHardware<GPR32Opnd, HWRegsOpnd>,
|
||||
@ -1068,6 +1052,11 @@ let Predicates = [InMicroMips] in {
|
||||
(LW_MM addr:$addr)>;
|
||||
def : MipsPat<(subc GPR32:$lhs, GPR32:$rhs),
|
||||
(SUBu_MM GPR32:$lhs, GPR32:$rhs)>;
|
||||
|
||||
def : MipsPat<(MipsTailCall (iPTR tglobaladdr:$dst)),
|
||||
(TAILCALL_MM tglobaladdr:$dst)>, ISA_MIPS1_NOT_32R6_64R6;
|
||||
def : MipsPat<(MipsTailCall (iPTR texternalsym:$dst)),
|
||||
(TAILCALL_MM texternalsym:$dst)>, ISA_MIPS1_NOT_32R6_64R6;
|
||||
}
|
||||
|
||||
let AddedComplexity = 40 in {
|
||||
|
@ -848,8 +848,6 @@ let AdditionalPredicates = [NotInMicroMips] in {
|
||||
def SDC2_R6 : SDC2_R6_ENC, SDC2_R6_DESC, ISA_MIPS32R6;
|
||||
def SWC2_R6 : SWC2_R6_ENC, SWC2_R6_DESC, ISA_MIPS32R6;
|
||||
}
|
||||
def TAILCALL_R6 : TailCall<J>, ISA_MIPS32R6;
|
||||
def TAILCALLREG_R6 : TailCallReg<GPR32Opnd, JR>, GPR_32, ISA_MIPS32R6;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
|
@ -242,9 +242,9 @@ let isCodeGenOnly = 1 in {
|
||||
def BLEZ64 : CBranchZero<"blez", brtarget, setle, GPR64Opnd>, BGEZ_FM<6, 0>;
|
||||
def BLTZ64 : CBranchZero<"bltz", brtarget, setlt, GPR64Opnd>, BGEZ_FM<1, 0>;
|
||||
def JALR64Pseudo : JumpLinkRegPseudo<GPR64Opnd, JALR, RA, GPR32Opnd>;
|
||||
def TAILCALLREG64 : TailCallReg<GPR64Opnd, JR64>, GPR_64, ISA_MIPS1_NOT_32R6_64R6;
|
||||
}
|
||||
|
||||
def TAILCALLREG64 : TailCallReg<GPR64Opnd>;
|
||||
|
||||
def PseudoReturn64 : PseudoReturnBase<GPR64Opnd>;
|
||||
def PseudoIndirectBranch64 : PseudoIndirectBranchBase<GPR64Opnd>;
|
||||
|
@ -165,10 +165,6 @@ def BLTZC64 : BLTZC_ENC, BLTZC64_DESC, ISA_MIPS64R6, GPR_64;
|
||||
def BGEZC64 : BGEZC_ENC, BGEZC64_DESC, ISA_MIPS64R6, GPR_64;
|
||||
}
|
||||
|
||||
def TAILCALL64_R6 : TailCall<J>, ISA_MIPS64R6;
|
||||
def TAILCALLREG64_R6 : TailCallReg<GPR64Opnd, JR64>, GPR_64,
|
||||
ISA_MIPS64R6;
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// Instruction Aliases
|
||||
|
@ -98,6 +98,7 @@ bool MipsAsmPrinter::lowerOperand(const MachineOperand &MO, MCOperand &MCOp) {
|
||||
void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
|
||||
const MachineInstr *MI) {
|
||||
bool HasLinkReg = false;
|
||||
bool InMicroMipsMode = Subtarget->inMicroMipsMode();
|
||||
MCInst TmpInst0;
|
||||
|
||||
if (Subtarget->hasMips64r6()) {
|
||||
@ -106,8 +107,12 @@ void MipsAsmPrinter::emitPseudoIndirectBranch(MCStreamer &OutStreamer,
|
||||
HasLinkReg = true;
|
||||
} else if (Subtarget->hasMips32r6()) {
|
||||
// MIPS32r6 should use (JALR ZERO, $rs)
|
||||
TmpInst0.setOpcode(Mips::JALR);
|
||||
HasLinkReg = true;
|
||||
if (InMicroMipsMode)
|
||||
TmpInst0.setOpcode(Mips::JRC16_MMR6);
|
||||
else {
|
||||
TmpInst0.setOpcode(Mips::JALR);
|
||||
HasLinkReg = true;
|
||||
}
|
||||
} else if (Subtarget->inMicroMipsMode())
|
||||
// microMIPS should use (JR_MM $rs)
|
||||
TmpInst0.setOpcode(Mips::JR_MM);
|
||||
@ -185,7 +190,9 @@ void MipsAsmPrinter::EmitInstruction(const MachineInstr *MI) {
|
||||
if (I->getOpcode() == Mips::PseudoReturn ||
|
||||
I->getOpcode() == Mips::PseudoReturn64 ||
|
||||
I->getOpcode() == Mips::PseudoIndirectBranch ||
|
||||
I->getOpcode() == Mips::PseudoIndirectBranch64) {
|
||||
I->getOpcode() == Mips::PseudoIndirectBranch64 ||
|
||||
I->getOpcode() == Mips::TAILCALLREG ||
|
||||
I->getOpcode() == Mips::TAILCALLREG64) {
|
||||
emitPseudoIndirectBranch(*OutStreamer, &*I);
|
||||
continue;
|
||||
}
|
||||
|
@ -560,7 +560,7 @@ static int getEquivalentCallShort(int Opcode) {
|
||||
return Mips::JALRS16_MM;
|
||||
case Mips::TAILCALL_MM:
|
||||
llvm_unreachable("Attempting to shorten the TAILCALL_MM pseudo!");
|
||||
case Mips::TAILCALLREG_MM:
|
||||
case Mips::TAILCALLREG:
|
||||
return Mips::JR16_MM;
|
||||
default:
|
||||
llvm_unreachable("Unexpected call instruction for microMIPS.");
|
||||
|
@ -282,7 +282,7 @@ unsigned MipsInstrInfo::getEquivalentCompactForm(
|
||||
case Mips::JR:
|
||||
case Mips::PseudoReturn:
|
||||
case Mips::PseudoIndirectBranch:
|
||||
case Mips::TAILCALLREG_MM:
|
||||
case Mips::TAILCALLREG:
|
||||
canUseShortMicroMipsCTI = true;
|
||||
break;
|
||||
}
|
||||
@ -363,8 +363,7 @@ unsigned MipsInstrInfo::getEquivalentCompactForm(
|
||||
case Mips::JR:
|
||||
case Mips::PseudoReturn:
|
||||
case Mips::PseudoIndirectBranch:
|
||||
case Mips::TAILCALLREG_MM:
|
||||
case Mips::TAILCALLREG_R6:
|
||||
case Mips::TAILCALLREG:
|
||||
if (canUseShortMicroMipsCTI)
|
||||
return Mips::JRC16_MM;
|
||||
return Mips::JIC;
|
||||
@ -373,7 +372,7 @@ unsigned MipsInstrInfo::getEquivalentCompactForm(
|
||||
case Mips::JR64:
|
||||
case Mips::PseudoReturn64:
|
||||
case Mips::PseudoIndirectBranch64:
|
||||
case Mips::TAILCALLREG64_R6:
|
||||
case Mips::TAILCALLREG64:
|
||||
return Mips::JIC64;
|
||||
case Mips::JALR64Pseudo:
|
||||
return Mips::JIALC64;
|
||||
|
@ -1370,14 +1370,12 @@ let isCall=1, hasDelaySlot=1, isCTI=1, Defs = [RA] in {
|
||||
|
||||
let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1, hasDelaySlot = 1,
|
||||
hasExtraSrcRegAllocReq = 1, isCTI = 1, Defs = [AT] in {
|
||||
class TailCall<Instruction JumpInst> :
|
||||
class TailCall<Instruction JumpInst, DAGOperand Opnd> :
|
||||
PseudoSE<(outs), (ins calltarget:$target), [], II_J>,
|
||||
PseudoInstExpansion<(JumpInst jmptarget:$target)>;
|
||||
PseudoInstExpansion<(JumpInst Opnd:$target)>;
|
||||
|
||||
class TailCallReg<RegisterOperand RO, Instruction JRInst,
|
||||
RegisterOperand ResRO = RO> :
|
||||
PseudoSE<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>,
|
||||
PseudoInstExpansion<(JRInst ResRO:$rs)>;
|
||||
class TailCallReg<RegisterOperand RO> :
|
||||
MipsPseudo<(outs), (ins RO:$rs), [(MipsTailCall RO:$rs)], II_JR>;
|
||||
}
|
||||
|
||||
class BAL_BR_Pseudo<Instruction RealInst> :
|
||||
@ -1919,11 +1917,12 @@ def BLTZALL : MMRel, BGEZAL_FT<"bltzall", brtarget, GPR32Opnd, 0>,
|
||||
BGEZAL_FM<0x12>, ISA_MIPS2_NOT_32R6_64R6;
|
||||
def BAL_BR : BAL_BR_Pseudo<BGEZAL>;
|
||||
|
||||
let AdditionalPredicates = [NotInMicroMips] in {
|
||||
def TAILCALL : TailCall<J>, ISA_MIPS1_NOT_32R6_64R6;
|
||||
def TAILCALLREG : TailCallReg<GPR32Opnd, JR>, ISA_MIPS1_NOT_32R6_64R6, GPR_32;
|
||||
let Predicates = [NotInMicroMips] in {
|
||||
def TAILCALL : TailCall<J, jmptarget>;
|
||||
}
|
||||
|
||||
def TAILCALLREG : TailCallReg<GPR32Opnd>;
|
||||
|
||||
// Indirect branches are matched as PseudoIndirectBranch/PseudoIndirectBranch64
|
||||
// then are expanded to JR, JR64, JALR, or JALR64 depending on the ISA.
|
||||
class PseudoIndirectBranchBase<RegisterOperand RO> :
|
||||
|
43
test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll
Normal file
43
test/CodeGen/Mips/tailcall/tailcall-wrong-isa.ll
Normal file
@ -0,0 +1,43 @@
|
||||
; RUN: llc -filetype=obj -march=mipsel -relocation-model=pic -verify-machineinstrs < %s -o - \
|
||||
; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=PIC32
|
||||
|
||||
; RUN: llc -filetype=obj -march=mipsel -relocation-model=static -verify-machineinstrs < %s -o - \
|
||||
; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=STATIC32
|
||||
|
||||
; RUN: llc -filetype=obj -march=mips64el -mcpu=mips64 -verify-machineinstrs < %s -o - \
|
||||
; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=N64
|
||||
|
||||
; RUN: llc -filetype=obj -march=mipsel -relocation-model=pic -mattr=+micromips < %s -o - \
|
||||
; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=PIC32MM
|
||||
|
||||
; RUN: llc -filetype=obj -march=mipsel -relocation-model=static -mattr=+micromips < %s -o - \
|
||||
; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=STATIC32MM
|
||||
|
||||
; RUN: llc -filetype=obj -march=mipsel -relocation-model=pic -mcpu=mips32r6 < %s -o - \
|
||||
; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=PIC32R6
|
||||
; RUN: llc -filetype=obj -march=mipsel -relocation-model=static -mcpu=mips32r6 < %s -o - \
|
||||
; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=STATIC32R6
|
||||
|
||||
; RUN: llc -filetype=obj -march=mips64el -mcpu=mips64r6 < %s -o - \
|
||||
; RUN: | llvm-objdump -d - | FileCheck %s -check-prefix=N64R6
|
||||
|
||||
declare i8 @f2(i8)
|
||||
|
||||
define i8 @f1(i8 signext %i) nounwind {
|
||||
%a = tail call i8 @f2(i8 %i)
|
||||
ret i8 %a
|
||||
}
|
||||
|
||||
; PIC32: {{[0-9]}}: 08 00 20 03 jr $25
|
||||
; STATIC32: {{[0-9]}}: 00 00 00 08 j 0
|
||||
|
||||
; N64: {{[0-9a-z]+}}: 08 00 20 03 jr $25
|
||||
|
||||
; PIC32MM: {{[0-9a-z]+}}: b9 45 jrc $25
|
||||
; STATIC32MM: {{[0-9]}}: 00 d4 00 00 j 0
|
||||
|
||||
; PIC32R6: {{[0-9]}}: 00 00 19 d8 jrc $25
|
||||
; STATIC32R6: {{[0-9]}}: 00 00 00 08 j 0
|
||||
|
||||
; N64R6: {{[0-9a-z]+}}: 09 00 20 03 jr $25
|
||||
|
Loading…
Reference in New Issue
Block a user