16

我正在为(ARM 64 位)平台musl-libc上的项目静态构建。aarch64我想避免使用任何软浮点库,例如GCC 的软浮点库例程。但是,即使我使用-mfloat-abi=hard. 据我所知,这是因为 ARM 64 位平台将 a 定义long double为 128 位。

有没有办法改变这种行为?例如,我可以强制long double定义为与 a 相同的大小double吗?我知道这是 C 标准允许的,但我不确定是否有任何方法可以强制 Clang(我专门为此使用 Clang)使用这样的定义进行编译。

4

2 回答 2

1

我最终找到了解决方案,尽管我不一定会向所有人推荐它。它可能会在其他地方引发错误,但它足以满足我的需要。它还涉及从头开始构建 Clang(感谢 @Art 的建议!)。此外,我正在进行的项目使用的是 LLVM/Clang 3.7.1,所以我对其他版本不做任何声明。


据我所知,AArch64 目标的 long double 的定义出现在clang/lib/Basic/Targets.cpp

...
MaxAtomicInlineWidth = 128;
MaxAtomicPromoteWidth = 128;

LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
LongDoubleFormat = &llvm::APFloat::IEEEquad;

// {} in inline assembly are neon specifiers, not assembly variant
// specifiers.
...

通过修改内部 2 行,我删除了对我在问题中提到的 soft-FP 例程的任何引用:

LongDoubleWidth = LongDoubleAlign = SuitableAlign = 64;
LongDoubleFormat = &llvm::APFloat::IEEEdouble;

我的测试程序——SNU 的 NASA Parallel Benchmarks 版本——仍然可以正确验证,所以我假设我没有严重破坏任何东西。尽管如此,这是一个重要的修改——我不建议大多数人使用它(它可能导致其他地方的损坏)。

于 2018-08-04T02:10:05.317 回答
0

我以前不得不做类似的事情,用类型(尤其是longs)弄乱。您最好的选择是手动手动替换类型,因为这是获得您想要的最简单和最直接的方法。您可以尝试使用宏或按摩编译器,但根据我的经验,您创建的问题比您解决的问题多,而且它通常是一个脆弱的解决方案,稍后会中断。

幸运的是,您正在使用的资源看起来维护得很好,并且您正在寻找的更改相当全面。你可以很简单地解决这个问题。假设您正在运行一个类 Unix 系统,您可以从 musl 的基本目录运行以下命令:

$ grep -Rl 'long double' * | xargs -tn1 sed -i '' -e 's/long double/double/g'

这个命令:

  1. 递归地在所有文件中查找字符串long double,并返回包含该字符串的文件名。
  2. 哪个被传递到xargs,谁调用sed每个文件名的命令,并随着它的进行打印。
  3. 运行时sed,它会就地修改文件,并long doubledouble.

当我尝试这个命令时,它“正常工作”。我会更仔细地阅读差异,以确保它正确地匹配所有内容并且不会改变库的行为。

于 2018-03-06T03:49:16.653 回答