Lorsque je compile du code C avec ma chaîne d'outils croisée, l'éditeur de liens imprime des pages d'avertissements indiquant que mon exécutable utilise des flottants durs mais que ma libc utilise des flotteurs souples. Quelle est la différence?
Les flotteurs durs utilisent une unité à virgule flottante sur puce. Les flotteurs souples émulent un dans le logiciel. La différence est la vitesse. Il est étrange de voir les deux utilisés sur la même architecture cible, car la puce possède ou non un FPU. Vous pouvez activer le virgule flottante douce dans GCC avec -msoft-float. Vous voudrez peut-être recompiler votre libc pour utiliser la virgule flottante matérielle si vous l'utilisez.
Il existe trois façons d'effectuer l'arithmétique en virgule flottante:
À strictement parler, toutes ces réponses me semblent fausses.
Lorsque je compile du code C avec ma chaîne d'outils croisée, l'éditeur de liens imprime des pages d'avertissements indiquant que mon exécutable utilise des flottants durs mais que ma libc utilise des flotteurs souples. Quelle est la différence?
Debian wiki VFP contient des informations sur les trois choix pour -mfloat-abi
,
soft
- c'est un pur logicielsoftfp
- cela prend en charge un FPU matériel, mais le [~ # ~] abi [~ # ~] est compatible soft.hard
- l'ABI utilise float ou [~ # ~] vfp [~ # ~] registres.L'erreur de l'éditeur de liens (chargeur) est due au fait que vous disposez d'une bibliothèque partagée qui transmettra des valeurs à virgule flottante dans les registres entiers. Vous pouvez toujours compiler votre code avec un -mfpu=vfp
, etc. mais vous devez utiliser -mfloat-abi=softfp
de sorte que si le libc a besoin d'un flottant, il est transmis d'une manière que la bibliothèque comprend.
Le noyau Linux peut prendre en charge l'émulation des instructions VFP. De toute évidence, il vaut mieux compiler avec -mfpu=none
dans ce cas et que la compilation génère directement du code au lieu de s'appuyer sur une émulation du noyau Linux. Cependant, je ne pense pas que l'erreur du PO soit réellement liée à ce problème. Il est distinct et doit également être traité avec le -mfloat-abi
.
bibliothèque partagée Armv5 avec CPU ArmV7 est un opposé à celui-ci; le libc était un flotteur dur mais l'application n'était que soft. Il a quelques façons de contourner le problème, mais la recompilation avec les bonnes options est toujours la plus simple.
Un autre problème est que le noyau Linux doit prendre en charge les tâches VFP (ou quoi que ce soit ARM virgule flottante est présent) pour enregistrer/restaurer les registres sur un changement de contexte.
Il semble que votre libc ait été conçue pour les opérations logicielles en virgule flottante tandis que votre exe a été compilé en supposant la prise en charge matérielle de la virgule flottante. À court terme, vous pouvez forcer les flottants flottants comme indicateur de compilation. (si vous utilisez gcc, je pense que c'est -msoft-float)
À plus long terme, si le processeur de votre cible prend en charge le matériel pour les opérations en virgule flottante, vous souhaiterez généralement créer ou trouver une chaîne d'outils croisée avec un flotteur matériel activé pour la vitesse. Certaines familles de processeurs ont des variantes de modèle, certaines avec ou sans support matériel. Ainsi, par exemple, dire simplement que votre processeur est un ARM est insuffisant pour savoir si vous avez un support matériel en virgule flottante.
Le calcul peut être effectué soit par du matériel à virgule flottante, soit par un logiciel basé sur l'arithmétique entière.
Le faire dans le matériel est beaucoup plus rapide, mais de nombreux microcontrôleurs n'ont pas de matériel à virgule flottante. Dans ce cas, vous pouvez soit éviter d'utiliser la virgule flottante (généralement la meilleure option), soit vous fier à une implémentation logicielle, qui fera partie de la bibliothèque C.
Dans certaines familles de contrôleurs, par exemple ARM, le matériel à virgule flottante est présent dans certains modèles de la famille mais pas dans d'autres, donc gcc pour ces familles prend en charge les deux. Votre problème semble être que vous avez mélangé les deux options.