Les membres ayant 30 points peuvent parler sur les canaux annonces, projets et hs du chat.
La shoutbox n'est pas chargée par défaut pour des raisons de performances. Cliquez pour charger.

Forum Casio - Projets de programmation


Index du Forum » Projets de programmation » Bibliothèque standard pour GCC
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1243 Défis: 54 Message

Bibliothèque standard pour GCC

Posté le 01/06/2014 19:50

Comme vous l'avez peut-être remarqué, LePhenixNoir nous a gratifié d'un tuto accessible afin de mettre en place GCC et donc une nouvelle manière de compiler des add-ins pour nos Casios.

Afin d'ouvrir le développement au libre, une bibliothèque C standard à vu le jour et avance petit à petit.
Un dépôt git est disponible ici.
L'objectif est, au final, d'avoir une bibliothèque dont on connaisse le contenu, qui soit maintenable et qui remplisse le rôle d'une librairie C standard à l'échelle de nos calculatrices, compatible SH4 et SH3, enfin un truc bien quoi !

Le code étant écrit par des membres de PC, depuis rien, le choix de la licence est ouvert, de mon côté, comme pour LePhenixNoir, placer celui-ci dans le domaine publique paraît intéressant, reste à voir avec les autres (notamment Dark Storm pour le moment ).
Message initial
Cliquer pour enrouler
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 !
[/spoiler]


Précédente 1, 2, 3 ··· 5, 6, 7, 8
Nemhardy Hors ligne Grand maître des Traits d'Esprit Points: 1243 Défis: 54 Message

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 :

float a = 2.5;
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 ?
Lephenixnoir Hors ligne Administrateur Points: 24575 Défis: 170 Message

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 ! >_<
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Dark storm En ligne Labélisateur Points: 11641 Défis: 176 Message

Citer : Posté le 18/06/2015 23:42 | #


Eh oui, GCC est assez performant

Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Lephenixnoir Hors ligne Administrateur Points: 24575 Défis: 170 Message

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.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Dark storm En ligne Labélisateur Points: 11641 Défis: 176 Message

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 :

int i = 0;
while(str[i++]);
return i;

Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Lephenixnoir Hors ligne Administrateur Points: 24575 Défis: 170 Message

Citer : Posté le 19/06/2015 08:01 | #


Ah ouais, tu crois ?

[b]libfx_original.a/strlen.robj:[/b]
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 :
%3d    => ' 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.

Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Dark storm En ligne Labélisateur Points: 11641 Défis: 176 Message

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 ?
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Lephenixnoir Hors ligne Administrateur Points: 24575 Défis: 170 Message

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.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Dark storm En ligne Labélisateur Points: 11641 Défis: 176 Message

Citer : Posté le 24/07/2015 20:44 | #


Ben t'en crée un sur Bitbucket ou GitLab
Finir est souvent bien plus difficile que commencer. — Jack Beauregard
Lephenixnoir Hors ligne Administrateur Points: 24575 Défis: 170 Message

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.
Mon graphe (11 Avril): ((Rogue Life || HH2) ; PythonExtra ; serial gint ; Boson X ; passe gint 3 ; ...) || (shoutbox v5 ; v5)
Précédente 1, 2, 3 ··· 5, 6, 7, 8

LienAjouter une imageAjouter une vidéoAjouter un lien vers un profilAjouter du codeCiterAjouter un spoiler(texte affichable/masquable par un clic)Ajouter une barre de progressionItaliqueGrasSoulignéAfficher du texte barréCentréJustifiéPlus petitPlus grandPlus de smileys !
Cliquez pour épingler Cliquez pour détacher Cliquez pour fermer
Alignement de l'image: Redimensionnement de l'image (en pixel):
Afficher la liste des membres
:bow: :cool: :good: :love: ^^
:omg: :fusil: :aie: :argh: :mdr:
:boulet2: :thx: :champ: :whistle: :bounce:
valider
 :)  ;)  :D  :p
 :lol:  8)  :(  :@
 0_0  :oops:  :grr:  :E
 :O  :sry:  :mmm:  :waza:
 :'(  :here:  ^^  >:)

Σ π θ ± α β γ δ Δ σ λ
Veuillez donner la réponse en chiffre
Vous devez activer le Javascript dans votre navigateur pour pouvoir valider ce formulaire.

Si vous n'avez pas volontairement désactivé cette fonctionnalité de votre navigateur, il s'agit probablement d'un bug : contactez l'équipe de Planète Casio.

Planète Casio v4.3 © créé par Neuronix et Muelsaco 2004 - 2024 | Il y a 199 connectés | Nous contacter | Qui sommes-nous ? | Licences et remerciements

Planète Casio est un site communautaire non affilié à Casio. Toute reproduction de Planète Casio, même partielle, est interdite.
Les programmes et autres publications présentes sur Planète Casio restent la propriété de leurs auteurs et peuvent être soumis à des licences ou copyrights.
CASIO est une marque déposée par CASIO Computer Co., Ltd