1

Comment optimiser plus les routines suivantes (particulièrement __sprintf_ulong_10__) ? Aussi, est-il vraiment intéressant de mettre __attribute__((__regparm__)) ?
void __attribute__((__stkparm__)) __sprintf_ushort_16__(unsigned char *str, unsigned short val); asm(" __sprintf_ushort_16__:         movem.l  %d0-%d6/%a0-%a1,-(%sp)         lea      -6(%sp),%sp         movea.l  %sp,%a0         moveq    #0x30,%d1         moveq    #0x41-10,%d2         moveq    #0xF,%d3         moveq    #0x9,%d4         movea.l  46(%sp),%a1         move.w   50(%sp),%d5         bne.s    __sus16_loop__         move.b   %d1,(%a1)+         bra.s    __sus16_cleanup_and_bye__ ___sus16_loop__:         lsr.w    #4,%d5 __sus16_loop__:         move.w   %d5,%d6         beq.s    __sus16_prepare_copy__         and.w    %d3,%d6         cmp.w    %d4,%d6         bhi.s    _sus16_loop__         add.w    %d1,%d6         move.b   %d6,(%a0)+         bra.s    ___sus16_loop__ _sus16_loop__:         add.w    %d2,%d6         move.b   %d6,(%a0)+         bra.s    ___sus16_loop__    __sus16_prepare_copy__:         move.l   %a0,%d0         sub.l    %sp,%d0         subq.b   #1,%d0 __sus16_copy__:         move.b   -(%a0),(%a1)+         dbf      %d0,__sus16_copy__ __sus16_cleanup_and_bye__:         clr.b    (%a1)         lea      6(%sp),%sp         movem.l  (%sp)+,%d0-%d6/%a0-%a1         rts"); void __attribute__((__stkparm__)) __sprintf_ulong_16__(unsigned char *str, unsigned long val); asm(" __sprintf_ulong_16__:         movem.l  %d0-%d6/%a0-%a1,-(%sp)         lea      -12(%sp),%sp         movea.l  %sp,%a0         moveq    #0x30,%d1         moveq    #0x41-10,%d2         moveq    #0xF,%d3         moveq    #0x9,%d4         movea.l  52(%sp),%a1         move.l   56(%sp),%d5         bne.s    __sul16_loop__         move.b   %d1,(%a1)+         bra.s    __sul16_cleanup_and_bye__ ___sul16_loop__:         lsr.l    #4,%d5 __sul16_loop__:         move.l   %d5,%d6         beq.s    __sul16_prepare_copy__         and.w    %d3,%d6         cmp.w    %d4,%d6         bhi.s    _sul16_loop__         add.w    %d1,%d6         move.b   %d6,(%a0)+         bra.s    ___sul16_loop__ _sul16_loop__:         add.w    %d2,%d6         move.b   %d6,(%a0)+         bra.s    ___sul16_loop__    __sul16_prepare_copy__:         move.l   %a0,%d0         sub.l    %sp,%d0         subq.b   #1,%d0 __sul16_copy__:         move.b   -(%a0),(%a1)+         dbf      %d0,__sul16_copy__ __sul16_cleanup_and_bye__:         clr.b    (%a1)         lea      12(%sp),%sp         movem.l  (%sp)+,%d0-%d6/%a0-%a1         rts"); void __attribute__((__stkparm__)) __sprintf_ushort_10__(unsigned char *str, unsigned short val); asm(" __sprintf_ushort_10__:         movem.l  %d0-%d3/%a0-%a1,-(%sp)         lea      -6(%sp),%sp         movea.l  %sp,%a0         moveq    #0x30,%d1         movea.l  34(%sp),%a1         move.w   38(%sp),%d2         cmpi.w   #9,%d2         bhi.s    __sus10_loop__ ___sus10_prepare_copy__:         add.b    %d1,%d2         move.b   %d2,(%a1)+         bra.s    __sus10_cleanup_and_bye__         __sus10_loop__:         divu.w   #10,%d2         swap     %d2         beq.s    __sus10_prepare_copy__         move.w   %d2,%d3         add.b    %d1,%d3         move.b   %d3,(%a0)+         clr.w    %d2         swap     %d2         bra.s    __sus10_loop__ __sus10_prepare_copy__:         move.l   %a0,%d0         sub.l    %sp,%d0         subq.b   #1,%d0 __sus10_copy__:         move.b   -(%a0),(%a1)+         dbf      %d0,__sus10_copy__ __sus10_cleanup_and_bye__:         clr.b    (%a1)         lea      6(%sp),%sp         movem.l  (%sp)+,%d0-%d3/%a0-%a1         rts"); void __attribute__((__stkparm__)) __sprintf_ulong_10__(unsigned char *str, unsigned long val); asm(" __sprintf_ulong_10__:         movem.l  %d0-%d3/%a0-%a1,-(%sp)         lea      -12(%sp),%sp         movea.l  %sp,%a0         moveq    #0x30,%d1         moveq    #0x9,%d7         movea.l  40(%sp),%a1         move.l   44(%sp),%d2         cmp.l    %d7,%d2         bhi.s    _sul10_loop__ ___sul10_prepare_copy__:         add.b    %d1,%d2         move.b   %d2,(%a1)+         bra.s    __sul10_cleanup_and_bye__ _sul10_loop__: | To have 10 and not 9 in d7. This is done in order to avoid a cmpi.l #9,%d2 | above...         addq.b   #1,%d7 __sul10_loop__: | The following may seem very stupid, but is there a faster way to test if | a data register is equal to 0 ?         move.l   %d2,%d2         beq.s    __sul10_prepare_copy__ | Clear the registers...         moveq    #0,%d3         moveq    #0,%d4 | Copy to the registers         move.w   %d2,%d3         swap     %d2         move.w   %d2,%d4         move.w   %d3,%d5 | Make the divisions         divu.w   %d7,%d3         divu.w   %d7,%d4         move.l   %d4,%d2         clr.w    %d2         move.w   %d5,%d2         divu.w   %d7,%d2         swap     %d2 | d6.w = remainder in the division of d2 by 10.         move.w   %d2,%d6         move.w   %d4,%d2         swap     %d2         add.b    %d1,%d6         move.b   %d6,(%a0)+         bra.s    __sul10_loop__ __sul10_prepare_copy__:         move.l   %a0,%d0         sub.l    %sp,%d0         subq.b   #1,%d0 __sul10_copy__:         move.b   -(%a0),(%a1)+         dbf      %d0,__sul10_copy__ __sul10_cleanup_and_bye__:         clr.b    (%a1)         lea      12(%sp),%sp         movem.l  (%sp)+,%d0-%d3/%a0-%a1         rts");

Merci d'avance.
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

2

XDanger
a écrit : Aussi, est-il vraiment intéressant de mettre __attribute__((__regparm__)) ?

C'est une fonction que GCC appellera en interne (comme __divsi3 etc.)? Si oui, c'est stkparm obligatoire pour le moment. sad
Sinon, le plus intéressant est le suivant:
void __sprintf_ushort_16__(unsigned char *str asm("a1"), unsigned short val asm("d5"));
void __sprintf_ulong_16__(unsigned char *str asm("a1"), unsigned long val asm("d5"));
void __sprintf_ushort_10__(unsigned char *str asm("a1"), unsigned short val asm("d2"));
void __sprintf_ulong_10__(unsigned char *str asm("a1"), unsigned long val asm("d2"));
Il suffit de regarder ton code source pour voir pourquoi.
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

3

Oui, ce sont des fonctions que je compte intégrer à TIGCC. Donc c'est stkparm obligatoire... tsss

Je me suis rendu compte que __sprintf_ulong_10__ sauve d0-d3/a0-a1 et détruit d0-d7/a0-a1... C'est vraiment pas beau ce que j'ai fait !
On doit pouvoir optimiser __sprintf_ulong_10__ en changeant les registres (raccourcir peut-être d'une ou deux instructions les lignes 155 à 170).
Et ce n'est pas possible de se passer des 3 divisions, ça m'ennuie...
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.

4

Les divisions par des constantes peuvent se remplacer par une méthode 2 fois plus rapide : topics/15118-multiplication#7, mais il faut voir la précision du résultat qui est parfois moyenne avec certaines constantes.
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

5

Thibaut a écrit :
Les divisions par des constantes peuvent se remplacer par une méthode 2 fois plus rapide : topics/15118-multiplication#7, mais il faut voir la précision du résultat qui est parfois moyenne avec certaines constantes.

Désolé, sprintf a besoin de 100% de précision!
avatar
Mes news pour calculatrices TI: Ti-Gen
Mes projets PC pour calculatrices TI: TIGCC, CalcForge (CalcForgeLP, Emu-TIGCC)
Mes chans IRC: #tigcc et #inspired sur irc.freequest.net (UTF-8)

Liberté, Égalité, Fraternité

6

Pour certaines constantes le résultat est aussi précis qu'une vraie division. Pour 10 c'est clair que c'est pas très bon smile
avatar
Un site complet sur lequel vous trouverez des programmes et des jeux pour votre calculatrice TI 89 / Titanium / 92+ / Voyage 200 : www.ti-fr.com.
Quelques idées personnelles ici.

7

Il se trouve que j'avais vu le topic dont tu parles.
Mais le topic parle de la division par 10 (de plus, la méthode n'est pas 100% précise, alors qu'il faut 100% de précision)... et moi j'ai besoin du modulo 10...
Et à moins que je sois trop fatigué pour réfléchir correctement, il me semble que: x*6553 >> 16 ne donne pas le modulo...
Par contre, si un jour j'ai besoin de la division par 10 et que je me moque de la précision, j'utiliserai probablement la méthode que tu as donnée...
avatar
Membre de la TI-Chess Team.
Co-mainteneur de GCC4TI (documentation en ligne de GCC4TI), TIEmu et TILP.
Co-admin de TI-Planet.