在 ARM 平台上正确检测混合端浮点格式
Posted
技术标签:
【中文标题】在 ARM 平台上正确检测混合端浮点格式【英文标题】:Correctly detect mixed-endian floating point format on ARM platform 【发布时间】:2014-09-29 17:39:50 【问题描述】:我最近遇到了一个第三方库的问题,该库使用以下代码在 ARM 平台上测试混合端浮点格式:
#if defined(__arm__) && !(__ARM_EABI__)
此检查在 android 平台上错误地检测混合端格式,但在 ios 平台上正常工作。经过一番研究,我发现debian ArmEabiPort document 在 GCC preprocessor macros for floating point 部分中包含以下内容(emphasis mine):
将代码移植到“armel”时,以下预处理器宏是 有趣:
__VFP_FP__ 表示使用的浮点格式是 ARM VFP 单元的格式,即本机字节序 IEEE-754。
__MAVERICK__ 表示浮点格式是 Cirrus Logic MaverickCrunch 的格式,它也是 IEEE-754 并且始终是 little-endian。
__SOFTFP__ 表示正在为浮点数学运算生成库调用而不是浮点指令,以便代码将在没有 FPU 的处理器上运行。
__VFP_FP__ 和 __MAVERICK__ 是互斥的。 如果两者都没有设置,则表示使用的浮点格式是 FPA 单元的旧混合端 45670123 格式。
对于我们的特定情况,将检查更新为以下解决了问题:
#if defined(__arm__) && !(__VFP_FP__)
适用于 Android 和 iOS 平台。虽然从文档中更正确的检查是:
#if defined(__arm__) && !(__VFP_FP__) && !(__MAVERICK__)
我们想将补丁提交给第三方,但考虑到旧支票确实对提交它的人有用,而且找到文档有多困难,我觉得我没有足够的信息来获取这个正确的。
是否存在最后一次检查未命中的情况? debian 文档具体涵盖了gcc
,这些宏的可移植性如何?
更新
根据从无艺术噪音中获得帮助的 cmets,问题归结为:
__ARM_EABI__
宏检查是由另一个用户作为补丁引入的,用于检查混合端浮点格式。显然,这个宏适用于某些系统,这些系统是什么系统? __VFP_FP__
宏是否会覆盖这些系统,或者我是否还需要考虑该宏以防止在我提交补丁时破坏现有用户。
【问题讨论】:
@artlessnoise 标记了gcc
,因为这是我们目前正在构建的,但我可能应该删除该标记,因为它有点令人困惑。由于我们想将补丁提交回开源项目,因此理想情况下代码应该更具可移植性,但我们无法验证,我怀疑该项目也可以。
@artlessnoise 至于 VFP 的报价,其余部分说 它只说使用中的浮点数据格式,这是我们关心的,我编辑了帖子提到我们关心浮点格式。
@artlessnoise 个人使用gcc 4.8
及更高版本和clang 3.4
及更高版本。这些平台是相对较新的 Android 和 iOS 设备。根据您的初步评论,真正可移植的检查可能很困难,至少更好地了解限制会很好。是否存在原始检查适用但我使用的新检查不适用的平台?
对于那个用例,我认为Cirrus Logic EP93xx ARM 可能不值得担心;这听起来像现代手机操作系统。我认为 ARM_EABI 的目的是检测传递信息?似乎ARM_PCS 是 gcc4.6+ 的更好方法。是交换传递的参数还是指针数据?似乎 VFP_FP 可能取决于所选的 CPU 类型。在 Cortex-A5 上,我一直使用 gcc 得到 VFP_FP,但在 ARM926(非常旧的 ARM 类型)上却没有。
@artlessnoise 谢谢你,你的 cmets 很有帮助。我更新了我的问题。
【参考方案1】:
您还需要检查以确保您不在软浮动工具链上,因为软浮动库不存在混合端问题:
#if defined(arm) && !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__MAVERICK__)
至于编译器支持——这些应该可以在 clang 中工作,但很明显,商业 ARM 编译器将完全做其他事情。
【讨论】:
以上是关于在 ARM 平台上正确检测混合端浮点格式的主要内容,如果未能解决你的问题,请参考以下文章