Use ARMPseudoExpand for ARM tail calls.

llvm-svn: 134719
This commit is contained in:
Jim Grosbach 2011-07-08 18:50:22 +00:00
parent 8fa5e7605f
commit 435ca7304c
3 changed files with 28 additions and 42 deletions

View File

@ -1801,20 +1801,6 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
}
// Tail jump branches are really just branch instructions with additional
// code-gen attributes. Convert them to the canonical form here.
case ARM::TAILJMPd:
case ARM::TAILJMPdND: {
MCInst TmpInst, TmpInst2;
// Lower the instruction as-is to get the operands properly converted.
LowerARMMachineInstrToMCInst(MI, TmpInst2, *this);
TmpInst.setOpcode(ARM::Bcc);
TmpInst.addOperand(TmpInst2.getOperand(0));
// Add predicate operands.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));
TmpInst.addOperand(MCOperand::CreateReg(0));
OutStreamer.AddComment("TAILCALL");
OutStreamer.EmitInstruction(TmpInst);
return;
}
case ARM::tTAILJMPd:
case ARM::tTAILJMPdND: {
MCInst TmpInst, TmpInst2;
@ -1827,14 +1813,10 @@ void ARMAsmPrinter::EmitInstruction(const MachineInstr *MI) {
OutStreamer.EmitInstruction(TmpInst);
return;
}
case ARM::TAILJMPrND:
case ARM::tTAILJMPrND:
case ARM::TAILJMPr:
case ARM::tTAILJMPr: {
unsigned newOpc = (Opc == ARM::TAILJMPr || Opc == ARM::TAILJMPrND)
? ARM::BX : ARM::tBX;
MCInst TmpInst;
TmpInst.setOpcode(newOpc);
TmpInst.setOpcode(ARM::tBX);
TmpInst.addOperand(MCOperand::CreateReg(MI->getOperand(0).getReg()));
// Predicate.
TmpInst.addOperand(MCOperand::CreateImm(ARMCC::AL));

View File

@ -1538,17 +1538,19 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
def TCRETURNri : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
IIC_Br, []>, Requires<[IsDarwin]>;
def TAILJMPd : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
Size4Bytes, IIC_Br,
[]>, Requires<[IsARM, IsDarwin]>;
def TAILJMPd : ARMPseudoExpand<(outs), (ins br_target:$dst, variable_ops),
Size4Bytes, IIC_Br, [],
(Bcc br_target:$dst, (ops 14, zero_reg))>,
Requires<[IsARM, IsDarwin]>;
def tTAILJMPd: tPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
Size4Bytes, IIC_Br,
[]>, Requires<[IsThumb, IsDarwin]>;
def TAILJMPr : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
Size4Bytes, IIC_Br,
[]>, Requires<[IsARM, IsDarwin]>;
def TAILJMPr : ARMPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
Size4Bytes, IIC_Br, [],
(BX GPR:$dst)>,
Requires<[IsARM, IsDarwin]>;
def tTAILJMPr : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
Size4Bytes, IIC_Br,
@ -1564,17 +1566,19 @@ let isCall = 1, isTerminator = 1, isReturn = 1, isBarrier = 1 in {
def TCRETURNriND : PseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
IIC_Br, []>, Requires<[IsNotDarwin]>;
def TAILJMPdND : ARMPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
Size4Bytes, IIC_Br,
[]>, Requires<[IsARM, IsNotDarwin]>;
def TAILJMPdND : ARMPseudoExpand<(outs), (ins brtarget:$dst, variable_ops),
Size4Bytes, IIC_Br, [],
(Bcc br_target:$dst, (ops 14, zero_reg))>,
Requires<[IsARM, IsNotDarwin]>;
def tTAILJMPdND : tPseudoInst<(outs), (ins brtarget:$dst, variable_ops),
Size4Bytes, IIC_Br,
[]>, Requires<[IsThumb, IsNotDarwin]>;
def TAILJMPrND : ARMPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
Size4Bytes, IIC_Br,
[]>, Requires<[IsARM, IsNotDarwin]>;
def TAILJMPrND : ARMPseudoExpand<(outs), (ins tcGPR:$dst, variable_ops),
Size4Bytes, IIC_Br, [],
(BX GPR:$dst)>,
Requires<[IsARM, IsNotDarwin]>;
def tTAILJMPrND : tPseudoInst<(outs), (ins tcGPR:$dst, variable_ops),
Size4Bytes, IIC_Br,
[]>, Requires<[IsThumb, IsNotDarwin]>;

View File

@ -15,11 +15,11 @@ define void @t1() {
define void @t2() {
; CHECKV6: t2:
; CHECKV6: bx r0 @ TAILCALL
; CHECKV6: bx r0
; CHECKT2D: t2:
; CHECKT2D: ldr
; CHECKT2D-NEXT: ldr
; CHECKT2D-NEXT: bx r0 @ TAILCALL
; CHECKT2D-NEXT: bx r0
%tmp = load i32 ()** @t ; <i32 ()*> [#uses=1]
%tmp.upgrd.2 = tail call i32 %tmp( ) ; <i32> [#uses=0]
ret void
@ -27,11 +27,11 @@ define void @t2() {
define void @t3() {
; CHECKV6: t3:
; CHECKV6: b _t2 @ TAILCALL
; CHECKV6: b _t2
; CHECKELF: t3:
; CHECKELF: b t2(PLT) @ TAILCALL
; CHECKELF: b t2(PLT)
; CHECKT2D: t3:
; CHECKT2D: b.w _t2 @ TAILCALL
; CHECKT2D: b.w _t2
tail call void @t2( ) ; <i32> [#uses=0]
ret void
@ -41,9 +41,9 @@ define void @t3() {
define double @t4(double %a) nounwind readonly ssp {
entry:
; CHECKV6: t4:
; CHECKV6: b _sin @ TAILCALL
; CHECKV6: b _sin
; CHECKELF: t4:
; CHECKELF: b sin(PLT) @ TAILCALL
; CHECKELF: b sin(PLT)
%0 = tail call double @sin(double %a) nounwind readonly ; <double> [#uses=1]
ret double %0
}
@ -51,9 +51,9 @@ entry:
define float @t5(float %a) nounwind readonly ssp {
entry:
; CHECKV6: t5:
; CHECKV6: b _sinf @ TAILCALL
; CHECKV6: b _sinf
; CHECKELF: t5:
; CHECKELF: b sinf(PLT) @ TAILCALL
; CHECKELF: b sinf(PLT)
%0 = tail call float @sinf(float %a) nounwind readonly ; <float> [#uses=1]
ret float %0
}
@ -65,9 +65,9 @@ declare double @sin(double) nounwind readonly
define i32 @t6(i32 %a, i32 %b) nounwind readnone {
entry:
; CHECKV6: t6:
; CHECKV6: b ___divsi3 @ TAILCALL
; CHECKV6: b ___divsi3
; CHECKELF: t6:
; CHECKELF: b __aeabi_idiv(PLT) @ TAILCALL
; CHECKELF: b __aeabi_idiv(PLT)
%0 = sdiv i32 %a, %b
ret i32 %0
}