alors voilà, chose promise, chose due, voici ce que donne gcc (syntaxe gcc
)
_fact:
link a6,#-4
tstl a6@(8)
jne L2
moveq #1,d0
movel d0,a6@(-4)
jra L1
.even
L2:
movel a6@(8),d0
subql #1,d0
movel d0,sp@-
jbsr _fact
addql #4,sp
mulsl a6@(8),d0
movel d0,a6@(-4)
L1:
movel a6@(-4),d0
unlk a6
rts
ok, j'entends d'ici certains compères qui commencent à rigoler
je vous l'accorde, le code ci-dessus n'est pas très performant
d'abord, règlons le cas des link/unlk qui sont inutiles ici (si vous avez quelques notions de compilation, a6 représente le "frame pointer")
ajoutons donc l'option -fomit-frame-pointer, cela donne:
_fact:
subqw #8,sp
tstl sp@(12)
jne L2
moveq #1,d0
movel d0,sp@
jra L1
.even
L2:
movel sp@(12),d0
subql #1,d0
movel d0,sp@-
jbsr _fact
addql #4,sp
mulsl sp@(12),d0
movel d0,sp@
L1:
movel sp@,d0
addqw #8,sp
rts
là, c'est déjà un peu mieux et à l'époque où j'ai désassemblé AviPlay de Dieter Fiebelkorn, je n'aurais pas ralé après tous ces link/unlk (qui me semblaient inutiles alors que je n'y connaissais rien en compilation)
voyons voir maintenant ce que donne l'option -O2
_fact:
movel d2,sp@-
movel sp@(8),d2
moveq #1,d0
tstl d2
jeq L1
movel d2,a0
pea a0@(-1)
jbsr _fact
mulsl d2,d0
addql #4,sp
.even
L1:
movel sp@+,d2
rts
en fait, c'est là que j'ai été un peu surpris par l'utilisation de pea pour calculer (n-1) et en même temps empiler le paramètre
(je n'aurais jamais pensé à ça en fait !)
je suis content d'avoir appris cette optim en tout cas
enfin, voici ce que donne gcc quand on donne comme processeur m68000 au lieu de m680x0 (par défaut), avec -fomit-frame-pointer et -O2
_fact:
movel a2,sp@-
movel sp@(8),a2
moveq #1,d0
cmpw #0,a2
jeq L1
pea a2@(-1)
jbsr _fact
movel d0,sp@-
movel a2,sp@-
jbsr ___mulsi3
lea sp@(12),sp
.even
L1:
movel sp@+,a2
rts
on remarque que là ce n'est plus mulsl qui est utilisé mais une fonction auxiliaire qui émule cette multiplication longue (modulo 2^32)
alors, vos impressions?