Seulement, si le support de l'architecture SuperH est relativment "natif" pour GCC, le support des librairies et des parties spécifique aux calculatrices Casio l'est beaucoup moins. Ainsi, si il est possible de récupérer les fonctions correspondants à "fxlib.h" dans un format utilisable par GCC, la librairie C standard fournie par casio dans le SDK ne semble pas aussi simple à récupérer (voire irrécupérable
? ).
Le plus simple est je pense de "réecrire" une bibliothèque standard C.
A mon avis, il pourrait aussi être intéressant d'essayer de s'affranchir de la bibliothèque "fxlib" fournie par Casio, toujours en la réecrivant (c'est à dire simplement refaire les appels de Syscalls pour la plupart des fonctions, "fxlib" étant majoritairement basée sur les Syscalls), mais en travaillant sur certains points et avoir d'emblée une compatibilité SH4 par exemple. On "enlèverait" aussi la plupart du code propriétaire de Casio (bien qu'il reste les syscalls, mais bon...
).
Ce qui concerne "fxlib" n'est que mon point de vue étant donné qu'on peut très bien conserver le fichier de Casio, j'amorce juste une réflexion à ce niveau là ;).
Quoi qu'il en soit, ce topic est là pour permettre de réfléchir sur le projet ,c'est à dire la réimplémentation d'une bibliothèque C à peu près standard (en s'appuyant sur les syscalls déjà existants, va faloir sortir la doc
) pour fonctionner sur GCC de manière correcte, voire plus intéressante que sur le SDK de Casio (pourquoi pas implémenter des fopen(...) par exemple, là encore, simple suggestion à cogiter
).
C'est aussi pour voir si il y a des gens qui seraient intéressés pour travailler là dessus, et voir vos idées sur la manière de travailler dessus.
Je pense qu'à la longue, un dépot git (ou autre) sur gitorious ou quelque chose du même style pourrait servir, qu'en dites vous ? Enfin, le projet semble intéressant, d'autant plus qu'un GCC bien fonctionnel pour compiler des add-ins, ça serait cool ! :D.
Donc n'hésitez pas à mettre vos idées pour commencer et avancer !
Citer : Posté le 22/04/2015 17:56 | #
Beau boulot d'investigation !
Les flottants ne sont-ils pas stockés sur deux registres "contigus" (ou alors au moins lorsque passés en arguments) ? Ça me dit quelque chose et ça expliquerait pourquoi ça fonctionne alors que r5 (ni r7 d'ailleurs, surtout que la fonction ne demande que 2 floats en argument) n'est jamais déterminé. Enfin, je vais relire la doc de ce côté là, je t'avouerai que ça fait un petit moment que je me suis pas plongé dans de l'asm...
Sinon, au niveau de la précision, je ne pense pas que ça soit un gros problème de se limiter à 3 ou 4 décimales, car en plus d’accélérer potentiellement certaines opérations, je ne vois pas trop de cas où ça poserait un sérieux problème (côté dev casio j'entends). Le tout c'est que les utilisateurs soient au courant.
Du coup, par rapport aux fixed, ils interviendraient uniquement en interne de la libC suivant ce que tu proposes ?
Je veux dire que si l'utilisateur a quelque part :
a /= 0.7;
Là c'est le compilo qui se charge de gérer ça (je vois pas trop comment on pourrait faire autrement sans toucher au compilateur lui même d'ailleurs ), mais lorsqu'il appellera cos ou exp ou une fonction de la libC qui a besoin de (en interne ou en argument)/ retourne un flottant, ce qu'on reverrai c'est en fait un fixed passé par la macro de conversion pour en faire un float c'est ça ? Et du coup ce qui est implémenté bosse avec le fixed ? C'est ce qu'il me semble avoir compris mais je suis pas très sûr...
Edit : ah oui et au niveau des syscalls : effectivement malloc et free font partie de ceux qu'on pourra bien utiliser, en comptant peut être aussi ceux qui opèrent sur les fichiers, je ne crois pas qu'on ait d'alternatives fiable et assez générale pour l'instant non ?
Citer : Posté le 22/04/2015 18:43 | #
Lorsqu'on a des constantes dans le code, le compilateur fait les calculs et n'assemble que le résultat.
Par contre, le problème c'est qu'on peut pas forcer le compilateur à appeler nos routines pour les fixed, autrement dit on devra utiliser des fonctions et non pas des opérateurs, en C pur du moins (de toute façon en C++, aucun intérêt ou presque), à moins de retirer les symboles de calcul de la libgcc et de foutre les nôtres, ce qui reste encore assez barbares (du coup, on remplace les double par des fixed et on adapte tout).
En général on procéderait du genre mon_fixed = fix(sqrt(unfix(mon_fix))); C'est lourd, ceci dit ça permet d'interfacer.
Évidemment, maintenant que je vois la doc ça me paraît tout à fait logique ce que tu dit à propos du stockage sur plusieurs registres.
Ceci dit, on peut très bien avoir des fonctions pour les fixed et d'autres pour les double, mais la vitesse sera pas la même.
Au fait, j'ai vu quelques trucs assez ahurissants dans la lib de Kristaba, notamment sur la gestion des signes à certains moments. Du genre a = x >> 5; if(a<0) { ... } : jusqu'à preuve du contraire, après ce décalage les 5 upper bits de a sont nuls donc a est forcément positif. (tu vois le principe je pense)
Je rencontre encore pas mal de problèmes mais d'après ce que je vois on a déjà moyen de faire pas mal de choses intéressantes, j'ai pas mal d'idées pratiques.
Pour les syscalls, on ne peut rien faire d'autre pour l'instant, en effet...
Ajouté le 18/06/2015 à 20:58 :
Ok, je voulais écrire un programme complet pour tester la vitesse des fonctions.
J'ai commencé par strlen(), mais dans l'assembleur compilé, aucune trace du symbole _strlen ni de l'appel à la fonction... j'ai fait quelques vérifications, mais même si j'arrive pas à la localiser dans le code, je pense qu'il l'a inliné et...
Oh, wait. Cet idiot de compilateur a repéré que mon paramètre de strlen() était constant et il l'a calculé à la compilation ! >_<
Citer : Posté le 18/06/2015 23:42 | #
Eh oui, GCC est assez performant
Citer : Posté le 19/06/2015 07:52 | #
Bon, j'ai écrit une fonction qui permet d'appeler n'importe quelle fonction avec n'importe quel paramètres, et qui compte le nombre d'itérations en un temps personnalisé.
J'espère que j'arriverai à une application efficace pour comparer la vitesse des fonctions.
Citer : Posté le 19/06/2015 07:56 | #
Au fait, le strlen testé, c'est celui de la fxlib ou un perso ? Parce que c'est quand même dur d'optimiser ça :
while(str[i++]);
return i;
Citer : Posté le 19/06/2015 08:01 | #
Ah ouais, tu crois ?
0: bra 6 <_strlen+0x6>
2: mov #0,r5
4: add #1,r5
6: mov.b @r4+,r3
8: tst r3,r3
a: bf 4 <_strlen+0x4>
c: rts
e: mov r5,r0
[b]libc/string/strlen.s:[/b]
_strlen:
/* Initializing length. */
mov #-1, r0
strlen_loop:
/* Getting the next character. */
mov.b @r4+, r1
/* Looping if not null. */
add #1, r0
tst r1, r1
bf strlen_loop
/* Returning. */
rts
nop
Edit: Je ne sais pas si ma version est plus optimisée hein, mais tu vois bien que c'est très différent.
Ajouté le 21/07/2015 à 16:53 :
Bon, j'ai encore bossé pas mal.
Point important : j'ai réussi à implémenter proprement exit(), abort() et atexit().
Ça fonctionne super bien. Du coup, ajoutez assert() qui supporte bien entendu la macro NDEBUG.
J'ai aussi écrit quelques fonctions de string en assembleur, à première vue ça fonctionne bien.
Je me suis replongé dans le code de la famille de printf(), qui est effectivement très lourd, actuellement pas loin de 2000 octets pour la procédure de base, incluant l'analyse du texte, des formats, et la sortie des entiers signés aux formats %d et %i.
Je l'ai réécrit de presque zéro pour la lisibilité, la maintenabilité et l'efficacité (au prix de quelques pertes de vitesse, je pense) et franchement c'est déjà bien plus clair. Sans compter que les commentaires servent maintenant à quelque chose.
Je pense ajouter les formats %c (facile), %s (facile aussi), %p (tranquille) et %o, %u, %x et %X (un peu plus long) assez vite.
Après ça il restera les flottants %e et %E (notation exponentielle), %f et %F (notation flottante classique), %g et %G (notation intelligente sous-traitant %e et %E ou %f et %F), et éventuellement %a et %A (flottant hexadécimal) bien que je ne sache pas encore comment l'implémenter.
Ah oui, je pourrai ajouter %n aussi : le nombre de caractères écrits au moment où le format est trouvé est écrit dans le pointeur correspondant envoyé en argument, et éventuellement %m (int), qui correspond à %s (strerror(int)).
Ajouté le 21/07/2015 à 22:22 :
Voilà, j'ai implémenté %c et %s. Les deux étaient somme toute largement faciles, et je commence à prendre le coup de main.
Faudrai voir pour les flottants par contre... Au fait, visiblement le format %lf n'est pas trop censé exister : il est souvent supporté mais pas standard ; en outre, %f prend déjà des double.
À ce stade (%d/%i, %c, %s), mon fichier objet (sans implémentations autres, juste une fonction d'interface et ses sous-routines) fait déjà 2228 octets.
Bon, on n'est pas encore aux 12'000 octets que Dark Storm a constaté il y a quelques jours mais c'est sûr que c'est pas des fonctions légères !
Au passage j'ai cherché dans fxlib, les objets de sprintf() et vsprintf() ne font que 800 octets (environ la taille d'une délégation à une fonction générique, étonnamment -il faudra que je creuse un peu-) donc je ne pense pas qu'ils contiennent le code en lui-même. J'ai regardé rapidement parmi les objets, seuls ceux-là contiennent des symboles contenant « print ».
Ajouté le 22/07/2015 à 09:45 :
Ouf, j'ai fini par démêler et implémenter le fonctionnement de %o, %u, %x et %X.
J'ai aussi trouvé des erreurs dans mon précédent formatage d'entier avec %d et %i : en effet, l'option '0' remplace les espaces par des zéros, mais pas si l'expression est alignée à gauche ! Et pas non plus si un nombre de zéros a été spécifié (via le nombre de digits décimaux).
Exemples avec la valeur 76 :
%03d => '076'
%-03d => '76 '
%7.4d => ' 0076'
%07.4d => ' 0076'
Ce genre du subtilités quoi... du coup j'ai établi une petite charte d'influence et précédence des options qui m'a l'air assez complète déjà.
Ah oui, j'ai aussi galéré parce qu'aux formats %o, %x et %X la forme alternative '%#' ajoute les préfixes '0', '0x' ou '0X'. Sauf que ceux-ci prennent la place d'espaces s'il y en a assez, ou de zéros sinon, mais seulement si l'option '0' est activée, bref, encore le bordel quoi.
Avec tout ça j'essaie de garder du code lisible et clair. x)
Au passage avec le code de test je suis à 800 lignes pour la version actuelle.
Citer : Posté le 24/07/2015 09:48 | #
Génial
T'essaye de commit ça sur le repo de la libc si ce n'est déjà fait ?
Citer : Posté le 24/07/2015 10:08 | #
Je te rappelle que gitorious est mort depuis un certain temps... Et je crois pas qu'on ait d'autre repo.
Citer : Posté le 24/07/2015 20:44 | #
Ben t'en crée un sur Bitbucket ou GitLab
Citer : Posté le 24/07/2015 21:14 | #
Voilà, c'est envoyé : https://bitbucket.org/Lephenixnoir/fx-9860g-libc .
Par pitié lisez la totalité du fichier LIBC avant de commenter quoi que ce soit, ok ?
Btw j'ai aussi implémenté %e (notation exponentielle), j'ai juste un problème d'arrondi.