Figuring out if parameter types are passed in same register

Assuming you use a x86_64, when you compile

extern void f1( long x);
extern void f2( void *x);

void g( void)
{
    f1( 1848);
    f2( (void *) 1848);
}

it compiles into identical argument passing code

    mov edi, 1848
    call _f1
    mov edi, 1848
    call _f2

This would not happen on a 680x0, because integers are passed in Dx registers and pointers in Ax registers (if I remember correctly).

Is there a way to figure out, given two types, if they are both passed using the same register ? [^1]

Ciao
    Nat!

[^1] It's given, that all preceeding argument types are known and same.

I’m assuming you are looking to “not reload edi”, but that’s not going to work if f1 or f2 makes any call that takes an argument [or edi is used for something else in the function!].

e.g.

void f1(long x)
{

f3(42);

}

which would lead to

mov edi, 42

call _f3;

so now edi is not the same any longer.

If you can inline the code (and f1 doesn’t make any calls or use edi for any other purpose), then the optimiser will remove the second load anyway.

Note that perhaps you are confusing the 32-bit calling convention where edi is a callee preserved register - but then it’s also not used to pass arguments either.

mats petersson wrote:

I'm assuming you are looking to "not reload edi", but that's not going
to work if f1 or f2 makes any call that takes an argument [or edi is
used for something else in the function!].

Actually no. In my case [^1] there is a trampoline function hidden between g and f and I would like to figure out, which kind of types I can pass transparently on the ABI/architecture.

So it would be more akin to

void f1( int x)
{
}

void call( void (*f)( void *), void *arg)
{
    (f)( arg);
}

void g()
{
    call( (void (*)( void *)) f1, (void *) 1848);
}

This would work on x86_64, but fail on 680x0 AFAIK.

To elaborate a bit more, if the parameters are passed on the stack, then trivially types of different size are bound to fail, thats why I am looking at registers only.

Thanks for the response.

Ciao
    Nat!

[^1] For the big picture view :slight_smile: https://www.mulle-kybernetik.com/weblog/2015/mulle_objc_meta_call_convention.html. I am currently doing "A more formal definition of the mulle-objc meta call convention" point 2.