diff --git a/lib/Target/ARM/ARMAsmPrinter.cpp b/lib/Target/ARM/ARMAsmPrinter.cpp index 5e58e84f70b..191fa1f35f2 100644 --- a/lib/Target/ARM/ARMAsmPrinter.cpp +++ b/lib/Target/ARM/ARMAsmPrinter.cpp @@ -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)); diff --git a/lib/Target/ARM/ARMInstrInfo.td b/lib/Target/ARM/ARMInstrInfo.td index 4bfe0672b2e..36c828564db 100644 --- a/lib/Target/ARM/ARMInstrInfo.td +++ b/lib/Target/ARM/ARMInstrInfo.td @@ -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]>; diff --git a/test/CodeGen/ARM/call-tc.ll b/test/CodeGen/ARM/call-tc.ll index c460f7a5bd0..e01750be81d 100644 --- a/test/CodeGen/ARM/call-tc.ll +++ b/test/CodeGen/ARM/call-tc.ll @@ -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 ; [#uses=1] %tmp.upgrd.2 = tail call i32 %tmp( ) ; [#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( ) ; [#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 ; [#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 ; [#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 }