Коли я компілюю код C моїм перехресним ланцюжком інструментів, компонувальник друкує сторінки з попередженнями про те, що мій виконуваний файл використовує жорсткі поплавки, але мій libc використовує м'які поплавки. Яка різниця?
Коли я компілюю код C моїм перехресним ланцюжком інструментів, компонувальник друкує сторінки з попередженнями про те, що мій виконуваний файл використовує жорсткі поплавки, але мій libc використовує м'які поплавки. Яка різниця?
Відповіді:
У жорстких поплавцях використовується вбудована одиниця з плаваючою комою. М'які поплавки імітують один у програмному забезпеченні. Різниця полягає в швидкості. Дивно бачити, як обидва вони використовуються в одній цільовій архітектурі, оскільки чіп або має FPU, або не має. Ви можете ввімкнути м’яку плаваючу крапку в GCC за допомогою -msoft-float. Можливо, вам захочеться перекомпілювати libc, щоб використовувати апаратне плаваючу крапку, якщо ви ним користуєтеся.
Існує три способи арифметики з плаваючою комою:
Власне кажучи, всі ці відповіді здаються мені неправильними.
Коли я компілюю код C моїм перехресним ланцюжком інструментів, компонувальник друкує сторінки з попередженнями про те, що мій виконуваний файл використовує жорсткі поплавки, але мій libc використовує м'які поплавки. Яка різниця?
Вікі-програма Debian VFP містить інформацію про три варіанти -mfloat-abi
,
soft
- це чисте програмне забезпеченняsoftfp
- це підтримує апаратний FPU, але ABI сумісний із програмним забезпеченням.hard
- ABI використовує плаваючі або VFP регістри.Помилка лінкера (навантажувача) пов’язана з тим, що у вас є спільна бібліотека, яка передаватиме значення з плаваючою комою в цілочисельні регістри. Ви все ще можете скомпілювати свій код за допомогою -mfpu=vfp
і т.д., але ви повинні використовувати -mfloat-abi=softfp
так, щоб, якщо libc потребує плаваючої форми, він передавався так, як це розуміє бібліотека.
Ядро Linux може підтримувати емуляцію інструкцій VFP. Очевидно, що вам краще компілювати -mfpu=none
для цього випадку і змусити компіляцію генерувати код безпосередньо, а не покладатися на будь-яку емуляцію ядра Linux. Однак я не вважаю, що помилка ОП насправді пов'язана з цією проблемою. Він окремий, і з ним також слід мати справу разом із -mfloat-abi
.
Спільна бібліотека Armv5 із процесором ArmV7 є протилежністю цій; Libc було важко поплавком , але застосування тільки м'яке . У ньому є кілька способів вирішити проблему, але перекомпіляція з правильними параметрами завжди є найпростішою.
Інша проблема полягає в тому, що ядро Linux повинно підтримувати завдання VFP (або будь-який інший ARM з плаваючою комою) для збереження / відновлення реєстрів на контекстному комутаторі.
Схоже, ваш libc був створений для програмних операцій з плаваючою комою, тоді як ваш exe був складений, передбачаючи апаратну підтримку з плаваючою комою. У короткостроковій перспективі ви можете примусити м'які плаваючі функції як прапор компілятора. (якщо ви використовуєте gcc, я думаю, що це -msoft-float)
Більш довгостроково, якщо ваш цільовий процесор має апаратну підтримку операцій із плаваючою комою, ви, як правило, захочете створити або знайти перехресний ланцюжок інструментів з увімкненим апаратним плаваючим процесором для швидкості. Деякі сімейства процесорів мають варіанти моделей, деякі з яких підтримують апаратне забезпечення, а інші - без них. Так, наприклад, просто сказати, що ваш процесор є ARM, недостатньо, щоб знати, чи підтримуєте ви апаратну підтримку з плаваючою комою.
Обчислення можуть здійснюватися як за допомогою апаратного забезпечення з плаваючою точкою, так і за допомогою програмного забезпечення на основі цілочисельної арифметики.
Робити це в апаратному забезпеченні набагато швидше, але багато мікроконтролери не мають апаратного забезпечення з плаваючою крапкою. У цьому випадку ви можете або уникати використання плаваючої крапки (зазвичай найкращий варіант), або покластися на реалізацію в програмному забезпеченні, яке буде частиною бібліотеки C.
У деяких сімействах контролерів, наприклад ARM, апаратне забезпечення з плаваючою точкою присутнє в деяких моделях сімейства, але не в інших, тому gcc для цих сімей підтримує обидва. Здається, ваша проблема полягає в тому, що ви змішали два варіанти.