7

我试图将大量代码塞进一个相当小的 ARM 微控制器中。我已经在尺寸优化方面做了大量工作,而且我已经到了需要双重算术的地步,但是__aeabi_ddiv,是整个设备上的一些最大功能__aeabi_dadd__aeabi_dsub

尽管做基本相同的工作(双打的最高位是符号位),但两者__aeabi_dadd都约为 1700 字节。__aeabi_dsub两个函数都没有引用另一个。

实际上,我需要做的就是替换__aeabi_dsub为:

double __aeabi_dsub(double a, double b) {
  // flip top bit of 64 bit number (the sign bit)
  ((uint32_t*)&b)[1] ^= 0x80000000; // assume little endian
  return a + b;
}

我会节省约 1700 个字节 - 所以翻转第二个参数的符号,然后使用__aeabi_dadd.

我知道这可能不是 100% 与 IEEE 规范兼容,但在这个平台上我可以接受,以便节省 1% 以上的可用闪存。

我的问题是,当我添加该函数时,链接器会抱怨undefined reference to __aeabi_dsub- 这似乎很奇怪,因为定义它的行为会导致错误。

-flto这似乎与链接时间优化有关(

__aeabi_dsub那么,当链接时间优化处于活动状态时,我需要做什么才能替换内置功能?

谢谢!

4

1 回答 1

1

我的解决方案(如@artless-noise 所建议)是使用-ffreestanding编译器标志。GCC 对此有话要说:

断言编译的目标是一个独立的环境......一个独立的环境是一个标准库可能不存在的环境,并且程序启动可能不一定在主环境中。最明显的例子是操作系统内核。

所以无论如何,对于嵌入式环境来说似乎很有意义......

这增加了大约 250 字节的固件大小(大约 0.1%),因为我猜它阻止了编译器利用有关内置运算符的一些假设,但是它确实允许我添加自己的__aeabi_dsub实现,总共节省了 1680 字节。

于 2021-01-11T08:34:56.917 回答