Hi.

Still trying to make a "fastcall" calling convention work on m68k. I
want functions marked as __attribute__((fastcall)) to pass arguments
in d0-2/a0-a1, this works for me.

I also want d2 to be properly marked as clobbered by "fastcall" calls.
This does not work for me. Or rather it works for the first call to a
function, but not for any further calls.

I have used the i386 port as the basis for my hack, thus only updating
call_used_regs from TARGET_CONDITIONAL_REGISTER_USAGE. I also
re-implemted TARGET_SET_CURRENT_FUNCTION and TARGET_EXPAND_TO_RTL_HOOK
to call reinit_regs() and reinit_target() as per i386.

Still it looks to me like upon completing the expansion of a function
call the call_used_regs of the current function is restored, and not
set again if calling the same function again.


Consider this C-code to compile:
#define FASTCALL __attribute__((fastcall))
#define MUL_ASSERT(a, b, c) my_assert(mul(a, b), a * b, c)
FASTCALL
int mul(int a, int b) {
    return a * b;
}
FASTCALL
void my_assert(int v, int e, int f) {
    if (v != e) {
        __asm__ __volatile__
        (
         "illegal\n\t"
         : /* outputs */
         : /* inputs */
         : /* clobbered regs */
         );
    }
}
int answer() {
    return 42;
}
int main(int argc, char* argv[])
{
    int a = answer();  // Default ABI d0-d1,a0-a1 used.
    MUL_ASSERT(0,0, a);  // "fastcall" ABI d0-d2,a0-a1 used
    MUL_ASSERT(1,0, a);  // ditto
    return 0;
}

====
This is the generated assembly for the main function:
_main:
    movem.l #12336,-(%sp)
    jsr ___main
    jar _answer
    move.l %d0,%d3   | result from anser() stored in d3, d2 is
correctly assumed clobbered later here.
    lea _mul,%a3
    moveq #0,%d1
    moveq #0,%d0
    jsr (%a3)   | Calling mul(int,int) here, d0-2/a0-1 clobbered, thi
is where d2 becomes clobbered.
    lea _my_assert,%a2
    move.l %d3,%d2  | For first call to my_assert() d3 correctly moved
down to d2 for arg passing.
    moveq #0,%d1
    jsr (%a2)  | Calling my_assert(), will clobber d0-d2/a0-a1
    moveq #0,%d1
    moveq #1,%d0
    jsr (%a3)  | Calling mul() again, will clobber.
    moveq #0,%d1
    jsr (%a2)  | This call to my_assert() d2 is incorrectly assumed to
be still valid from previous call. HOW can I fix this?
    moveq #0,%d0
    movem.l (%sp)+,#3084
    rts

// Fredrik Olsson

Reply via email to