Kiedy kompiluję kod C z moim krzyżowym łańcuchem narzędzi, linker drukuje strony z ostrzeżeniami, mówiąc, że mój plik wykonywalny używa twardych pływaków, ale moja biblioteka libc używa miękkich pływaków. Co za różnica?
Kiedy kompiluję kod C z moim krzyżowym łańcuchem narzędzi, linker drukuje strony z ostrzeżeniami, mówiąc, że mój plik wykonywalny używa twardych pływaków, ale moja biblioteka libc używa miękkich pływaków. Co za różnica?
Odpowiedzi:
Twarde spławiki używają wbudowanej jednostki zmiennoprzecinkowej. Miękkie pływaki emulują je w oprogramowaniu. Różnica polega na szybkości. Dziwne jest to, że oba są używane w tej samej architekturze docelowej, ponieważ chip albo ma FPU, albo go nie ma. Możesz włączyć miękki zmiennoprzecinkowy w GCC za pomocą -msoft-float. Możesz chcieć przekompilować swoją bibliotekę libc, aby używała sprzętowych wartości zmiennoprzecinkowych, jeśli jej używasz.
Istnieją trzy sposoby wykonywania arytmetyki zmiennoprzecinkowej:
Ściśle mówiąc, wszystkie te odpowiedzi wydają mi się błędne.
Kiedy kompiluję kod C z moim krzyżowym łańcuchem narzędzi, linker drukuje strony z ostrzeżeniami, mówiąc, że mój plik wykonywalny używa twardych pływaków, ale moja biblioteka libc używa miękkich pływaków. Co za różnica?
Debian VFP wiki zawiera informacje o trzech opcjach -mfloat-abi
:
soft
- to jest czyste oprogramowaniesoftfp
- obsługuje sprzętową FPU, ale ABI jest kompatybilny programowo.hard
- ABI używa rejestrów typu float lub VFP .Błąd konsolidatora (programu ładującego) jest spowodowany tym, że masz bibliotekę współdzieloną, która przekazuje wartości zmiennoprzecinkowe w rejestrach całkowitych. Nadal możesz skompilować swój kod za pomocą a -mfpu=vfp
, etc, ale powinieneś użyć -mfloat-abi=softfp
, aby jeśli biblioteka libc wymagała float, jest przekazywana w sposób zrozumiały dla biblioteki.
Jądro Linuksa może obsługiwać emulację instrukcji VFP. Oczywiście -mfpu=none
w tym przypadku lepiej jest skompilować się, a kompilacja generuje kod bezpośrednio, zamiast polegać na emulacji jądra Linuksa. Jednak nie sądzę, aby błąd OP był faktycznie związany z tym problemem. Jest oddzielny i należy go również rozwiązać wraz z plikiem -mfloat-abi
.
Biblioteka współdzielona Armv5 z procesorem ArmV7 jest przeciwieństwem tej; libc była ciężka pływak ale wniosek był tylko miękkie . Ma kilka sposobów obejścia tego problemu, ale rekompilacja z poprawnymi opcjami jest zawsze najłatwiejsza.
Inną kwestią jest to, że jądro Linuksa musi obsługiwać zadania VFP (lub jakikolwiek inny zmiennoprzecinkowy ARM), aby zapisać / przywrócić rejestry po przełączeniu kontekstu.
Wygląda na to, że libc zostało zbudowane do programowych operacji zmiennoprzecinkowych, podczas gdy twój exe został skompilowany przy założeniu sprzętowej obsługi zmiennoprzecinkowej. W krótkiej perspektywie możesz wymusić miękkie pływaki jako flagę kompilatora. (jeśli używasz gcc, myślę, że to -msoft-float)
W dłuższej perspektywie, jeśli procesor twojego celu obsługuje sprzętową obsługę operacji zmiennoprzecinkowych, generalnie będziesz chciał zbudować lub znaleźć krzyżowy łańcuch narzędzi z włączoną sprzętową funkcją float dla zwiększenia szybkości. Niektóre rodziny procesorów mają warianty modeli, niektóre ze wsparciem sprzętowym, a niektóre bez. Na przykład samo stwierdzenie, że procesor jest ARM, nie wystarczy, aby wiedzieć, czy masz sprzętową obsługę liczb zmiennoprzecinkowych.
Obliczenia można wykonać za pomocą sprzętu zmiennoprzecinkowego lub oprogramowania opartego na arytmetyce liczb całkowitych.
Robienie tego na sprzęcie jest znacznie szybsze, ale wiele mikrokontrolerów nie ma sprzętu zmiennoprzecinkowego. W takim przypadku możesz albo uniknąć używania zmiennoprzecinkowych opcji (zazwyczaj jest to najlepsza opcja), albo polegać na implementacji w oprogramowaniu, które będzie częścią biblioteki C.
W niektórych rodzinach kontrolerów, na przykład ARM, sprzęt zmiennoprzecinkowy jest obecny w niektórych modelach z rodziny, ale nie w innych, więc gcc dla tych rodzin obsługuje oba. Twój problem polega na tym, że pomieszałeś te dwie opcje.