arm tailcall with many parameters?

typedef struct vtable_t {
int (*pf4)(int a, int b, int c, int d);
int (*pf5)(int a, int b, int c, int d, int e);
} vtable_t;

int f1(int (*pf4)(int a, int b, int c, int d))
{
return pf4(1, 2, 3, 4);
}

int f2(vtable_t *vt)
{
return vt->pf4(1, 2, 3, 4);

}

gcc and clang will not tailcall these on arm with -O3.

int f3(int (*pf5)(int a, int b, int c, int d, int e))
{
return pf5(1, 2, 3, 4, 5);
}

int f4(vtable_t *vt)
{
return vt->pf5(1, 2, 3, 4, 5);
}

Could you not allocate an extra word on the stack,
in the first position, store the return address there, and pop
it to pc (or ip and then move to pc) after restoring nonvolatiles and lr?
Is that not describable in unwind data?

I only tested Debian’s 3.3 so far but I’ll try to try 6.0.

I ask because I’m working on tailcalls in another project.

I figured I’d look at gcc/clang output for hints here.

I understand there can be multiple exits of a function – tailcalls of varying signatures and non-tailcalls.

I don’t think that breaks the idea.

Thank you,

  • Jay

Sorry that also suffered from signature mismatch.

So how about more like:

typedef struct vtable_t {
int (*pf4)(int a, int b, int c, int d);
int (*pf5)(int a, int b, int c, int d, int e);
} vtable_t;

int f3(int (*pf5)(int a, int b, int c, int d, int e), int a, int b, int c, int d)

{
return pf5(a, b, c, d, d + d);
}
int f4(vtable_t *vt, int a, int b, int c, int d)
{
return vt->pf5(a, b, c, d, d + d);
}

  • Jay

Oh nevermind, that works.

  • Jay