C 强制64位长双倍?
我在一个C 强制64位长双倍?,c,floating-point,clang,arm64,musl,C,Floating Point,Clang,Arm64,Musl,我在一个aarch64(arm64位)平台上静态构建一个项目。我希望避免任何软浮点库,例如。但是,即使在我使用-mfloat abi=hard时,这些文件仍会出现在库档案中。据我所知,这是因为ARM 64位平台将长双精度定义为128位 有没有办法改变这种行为?例如,我是否可以强制将long double定义为与double相同的大小?我知道这是C标准允许的,但我不确定是否有任何方法可以强制使用Clang(我为此专门使用Clang)来编译这样一个定义。我以前也曾做过类似的事情,用类型(特别是lon
aarch64
(arm64位)平台上静态构建一个项目。我希望避免任何软浮点库,例如。但是,即使在我使用-mfloat abi=hard
时,这些文件仍会出现在库档案中。据我所知,这是因为ARM 64位平台将长双精度定义为128位
有没有办法改变这种行为?例如,我是否可以强制将
long double
定义为与double
相同的大小?我知道这是C标准允许的,但我不确定是否有任何方法可以强制使用Clang(我为此专门使用Clang)来编译这样一个定义。我以前也曾做过类似的事情,用类型(特别是long
s)来处理。最好的办法是手动替换类型,因为这是获得所需内容的最简单、最直接的方法。你可以试着用宏玩把戏或者修改编译器,但是根据我的经验,你只会产生比你解决的问题更多的问题,而且这通常是一个脆弱的解决方案,以后会崩溃
幸运的是,您正在使用的源代码看起来维护得很好,并且您正在寻找的更改非常简单。你可以很简单地解决这个问题。假设您运行的是类Unix系统,则可以从musl的基本目录运行以下命令:
$ grep -Rl 'long double' * | xargs -tn1 sed -i '' -e 's/long double/double/g'
此命令:
long double
,并返回包含该字符串的文件名xargs
,xargs调用每个文件名的sed
命令,并随文件一起打印sed
时,它会就地修改文件,并用double
替换long double
当我尝试这个命令时,它“刚刚起作用”。我会更仔细地阅读diff,以确保它符合所有要求,并且不会改变库的行为。我最终找到了一个解决方案,尽管我不一定推荐给所有人。它可能会在其他地方引发bug,但它已经足够满足我的需要了。它还包括从头开始构建叮当声(感谢@Art!)。此外,我正在从事的项目使用的是LLVM/Clang 3.7.1,因此我不主张使用其他版本
据我所知,AArch64目标的长双精度定义出现在: 通过修改内部2行,我删除了对我在问题中提到的软FP例程的任何引用:
LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;
我的测试程序--仍然正确地验证,所以我假设我没有太严重地破坏任何东西。不过,这是一个非常重要的修改——我不建议大多数人使用它(它可能会导致其他地方破损)。试试
-mlong-double-64
。不确定是否适用于ARM…@AndrewHenle:我假设软浮点库例程的出现仅仅是因为long double
被定义为128位(基于\uu extenddftff2
描述以及我知道我的aarch64
平台有64位FP寄存器的事实)。因此,虽然是的,vfprintf
依赖于long double
处理,但我想知道的是long double
处理是否反过来依赖于软浮点库例程。这有意义吗?@AndrewHenle:换句话说,如果vfprintf
依赖于long double
处理,那么long double
的大小是否会改变该处理?如果是这样的话,我可以利用这一事实强制长双精度的大小适应硬浮点寄存器,而不是使用软浮点吗?我知道这很可怕,但为了验证你的假设,为什么不执行查找替换(将“长双精度”替换为“双精度”)在我记忆中的整个库中?@tonysdg(这是一个永恒的过去),这需要重建编译器。也许叮当声是不同的,但对于gcc来说,这是唯一的选择。尽管我们确实大声发誓,体系结构定义了没有CPU(至今)拥有的类型和指令。事实上,我现在回想起来,我们的问题是双重的。在重建gcc之后,我们需要使用这些中止存根函数,以避免生成没有CPU实现的指令,并且我们没有在内核中进行仿真(就像其他人一样)。我有一个类似的例子:ppc32,gcc将长双精度运算编译成uu gcc_qsub/qmult/etc调用。GCC可以在没有quadmath的情况下编译工作,基本上可以将长的double减少到double。到目前为止,Clang不支持这一点。在源代码中更改它帮助了我!
LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;