On 05/15/2013 04:50 AM, Ramana Radhakrishnan wrote: > /* Cannot tail-call to long calls, since these are out of range of > a branch instruction. */ > - if (arm_is_long_call_p (decl)) > + if (decl && arm_is_long_call_p (decl)) > return false;
You can tail call long calls via indirection now. I.e. load the address first. > (define_insn "*sibcall_insn" > - [(call (mem:SI (match_operand:SI 0 "" "X")) > + [(call (mem:SI (match_operand:SI 0 "call_insn_operand" "Cs,Ss")) FWIW, "i" or "s" would work just as well, given you've already constrained by call_insn_operand; Ss isn't really needed. > + if (arm_arch5 || arm_arch4t) > + return \" bx\\t%0\\t%@ indirect register sibling call\"; Missing %?. > + if (arm_arch5 || arm_arch4t) > + return \"bx\\t%1\"; Likewise. > diff --git a/gcc/testsuite/gcc.target/arm/pr40887.c > b/gcc/testsuite/gcc.target/arm/pr40887.c > index 0b5e873..5cabe3a 100644 > --- a/gcc/testsuite/gcc.target/arm/pr40887.c > +++ b/gcc/testsuite/gcc.target/arm/pr40887.c > @@ -2,9 +2,9 @@ > /* { dg-options "-O2 -march=armv5te" } */ > /* { dg-final { scan-assembler "blx" } } */ > > -int (*indirect_func)(); > +int (*indirect_func)(int x); > > int indirect_call() > { > - return indirect_func(); > + return indirect_func(20) + indirect_func (40); > } > You've made this test case 100% useless. Of course there will always be a blx insn, since you've two calls there, and one of them will never be tail called. It should have been either removed or become your new test case. r~