Hi. As a learning project I have tried to implement "fastcall" for m68k target. I have largely sneak peeked at the i386 code to do this.
My "fastcall" convention uses d0-d2, a0-a1 and fp0-fp2 for arguments. This also means that d2 is clubbed by calls to functions using the "fastcall" ABI. I update the used regs and allocation order in function defined by TARGET_CONDITIONAL_REGISTER_USAGE. This works as expected until const moves are optimised from full "move.l" to only "move.b" or "move.w", then the optimisers seems to assume that d2 is still have all the zeros in the higher bits. I have met roads end in my adventure and would need a hint as to how to ensure a call clobbered reg is considered call clobbered also when optimising this case. I add the test.c source and generated assembly with my comments bellow. // Fredrik === test.c === #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 main(int argc, char* argv[]) { MUL_ASSERT(0,0, 10); MUL_ASSERT(1,0, 100); MUL_ASSERT(0,1, 1000); return 0; } === test.c === #NO_APP .text .even .globl _mul _mul: jsr ___mulsi3 rts .even .globl _my_assert _my_assert: cmp.l %d0,%d1 jeq .L2 #APP | 12 "test.c" 1 illegal | 0 "" 2 #NO_APP .L2: rts .even .globl _main _main: movem.l #8240,-(%sp) jsr ___main lea _mul,%a3 moveq #0,%d1 moveq #0,%d0 jsr (%a3) lea _my_assert,%a2 moveq #10,%d2 | HERE d2 is third arg to my_assert, fully set moveq #0,%d1 jsr (%a2) | d2 is clobbered. moveq #0,%d1 moveq #1,%d0 jsr (%a3) | d2 is clobbered again. move.b #100,%d2 | Here the optimizer believe d2 is still unclobbered moveq #0,%d1 jsr (%a2) moveq #1,%d1 moveq #0,%d0 jsr (%a3) move.w #1000,%d2 moveq #0,%d1 jsr (%a2) moveq #0,%d0 movem.l (%sp)+,#3076 rts