Khi tôi biên dịch mã C với chuỗi công cụ chéo của mình, trình liên kết in ra các trang cảnh báo nói rằng tệp thực thi của tôi sử dụng phao cứng nhưng libc của tôi sử dụng phao mềm. Có gì khác biệt?
Khi tôi biên dịch mã C với chuỗi công cụ chéo của mình, trình liên kết in ra các trang cảnh báo nói rằng tệp thực thi của tôi sử dụng phao cứng nhưng libc của tôi sử dụng phao mềm. Có gì khác biệt?
Câu trả lời:
Phao cứng sử dụng đơn vị dấu phẩy động trên chip. Các phao mềm giả lập một trong phần mềm. Sự khác biệt là tốc độ. Thật kỳ lạ khi cả hai được sử dụng trên cùng một kiến trúc mục tiêu, vì chip có FPU hoặc không. Bạn có thể bật dấu phẩy động mềm trong GCC với -msoft-float. Bạn có thể muốn biên dịch lại libc của mình để sử dụng dấu phẩy động phần cứng nếu bạn sử dụng nó.
Có ba cách để tính số học dấu phẩy động:
Nói một cách chính xác, tất cả những câu trả lời này dường như sai đối với tôi.
Khi tôi biên dịch mã C với chuỗi công cụ chéo của mình, trình liên kết in ra các trang cảnh báo nói rằng tệp thực thi của tôi sử dụng phao cứng nhưng libc của tôi sử dụng phao mềm. Có gì khác biệt?
Wiki VFP Debian có thông tin về ba lựa chọn cho -mfloat-abi
,
soft
- đây là phần mềm thuần túysoftfp
- cái này hỗ trợ FPU phần cứng, nhưng ABI tương thích mềm.hard
- ABI sử dụng thanh ghi float hoặc VFP .Lỗi trình liên kết (trình tải) là do bạn có một thư viện được chia sẻ sẽ chuyển các giá trị dấu phẩy động trong thanh ghi số nguyên. Bạn vẫn có thể biên dịch mã của mình với a -mfpu=vfp
, v.v. nhưng bạn nên sử dụng -mfloat-abi=softfp
để nếu libc cần float, nó sẽ được truyền theo cách mà thư viện hiểu được.
Nhân Linux có thể hỗ trợ mô phỏng các lệnh VFP. Rõ ràng, bạn nên biên dịch với -mfpu=none
trường hợp này và để trình biên dịch tạo mã trực tiếp thay vì dựa vào bất kỳ mô phỏng hạt nhân Linux nào. Tuy nhiên, tôi không tin rằng lỗi của OP thực sự liên quan đến vấn đề này. Nó là riêng biệt và cũng phải được xử lý cùng với -mfloat-abi
.
Thư viện chia sẻ Armv5 với CPU ArmV7 là đối lập với thư viện này; các libc là phao cứng nhưng ứng dụng chỉ mềm . Nó có một số cách để giải quyết vấn đề, nhưng biên dịch lại với các tùy chọn chính xác luôn là cách dễ dàng nhất.
Một vấn đề khác là nhân Linux phải hỗ trợ các tác vụ VFP (hoặc bất kỳ dấu phẩy động nào của ARM) để lưu / khôi phục các thanh ghi trên một công tắc ngữ cảnh.
Có vẻ như libc của bạn được xây dựng cho các hoạt động dấu phẩy động của phần mềm trong khi exe của bạn được biên dịch giả sử hỗ trợ phần cứng cho dấu phẩy động. Trong ngắn hạn, bạn có thể ép phao mềm làm cờ biên dịch. (nếu bạn đang sử dụng gcc, tôi nghĩ đó là -msoft-float)
Về lâu dài, nếu bộ xử lý mục tiêu của bạn có hỗ trợ phần cứng cho các hoạt động dấu phẩy động, nói chung, bạn sẽ muốn xây dựng hoặc tìm một chuỗi công cụ chéo có bật phần cứng float để tăng tốc độ. Một số họ bộ xử lý có các biến thể kiểu máy, một số có và một số không hỗ trợ phần cứng. Vì vậy, ví dụ, chỉ nói bộ xử lý của bạn là ARM là không đủ để biết liệu bạn có hỗ trợ dấu chấm động phần cứng hay không.
Việc tính toán có thể được thực hiện bằng phần cứng dấu phẩy động hoặc trong phần mềm dựa trên số học số nguyên.
Làm điều đó trong phần cứng nhanh hơn nhiều, nhưng nhiều bộ vi điều khiển không có phần cứng dấu phẩy động. Trong trường hợp đó, bạn có thể tránh sử dụng dấu phẩy động (thường là tùy chọn tốt nhất) hoặc dựa vào triển khai trong phần mềm, phần mềm này sẽ là một phần của thư viện C.
Trong một số họ bộ điều khiển, ví dụ như ARM, phần cứng dấu phẩy động hiện diện trong một số mô hình của họ nhưng không có trong các kiểu khác, vì vậy gcc cho các họ này hỗ trợ cả hai. Vấn đề của bạn dường như là bạn đã trộn lẫn hai tùy chọn.