sauf pour les fonctions qui renvoient void, dans ce cas-là c'est un tail-call si c'est la dernière instruction avant la fin de la fonction... (en optimisant les sauts inutiles et tout ça)
et c'est spécifié par aucune norme, sans compter que ça pourrait interférer avec les optimisations du compilo (i.e. si le compilo s'amuse à déplacer certaines instructions après l'appel, c'est foutu), et qu'en C++ avec RTTI c'est même pas la peine d'y penser si y a des objets avec un destructeur non-trivial dans la scope de l'appel ^^
Pour ce qui est de "call bidule; return" : c'est un peu plus compliqué que ça, puisqu'une fonction a souvent des choses à libérer sur la pile, donc entre le "call" et le "return". C'est vrai qu'avec une convention d'appel style "la fonction appelée dépile tous ses arguments puis retourne", ton tail call ne pose pas de problème :
bidule:
move.w (a7)+,d0
add.w (a7)+,d0
rts
appelant:
move.w (a7)+,d0
bne return
move.w d0,-(a7)
move.w d0,-(a7)
bra bidule
return
rts
Mais avec la convention cdecl utilisée avec la majorité des compilos, ce n'est possible que si la fonction appelante reçoit plus d'arguments sur la pile que la fonction appelée, ce qu'on pourrait éventuellement forcer artificiellement (si appelant qui a 1 argument appelle bidule à 2 arguments, dire à tout le monde de considérer qu'appelant en a 2 même si on n'en utilise qu'1), mais ça casserait la compilation séparée

Et on peut avoir des bonnes raisons d'utiliser cdecl (autres qu'historiques), notamment parce que ça doit être plus efficace pour le processeur (sinon il faut empiler *d'abord* le PC, empiler les arguments et ensuite utiliser une instruction de saut sans empilement du PC : c'est plus logique de faire saut et empilement en une seule étape).