替换 __aeabi_dsub 以节省空间(-flto 问题)

Gor*_*ams 7 c embedded gcc arm lto

我试图将大量代码塞进一个相当小的 ARM 微控制器中。我已经做了尺寸优化工作的巨量已经和我到哪里,我需要加倍运算的地步,但是__aeabi_ddiv__aeabi_dadd__aeabi_dsub一些最大的功能,整个设备上。

这两个__aeabi_dadd__aeabi_dsub是尽管基本上做同样的工作〜1700 bytes每个(双打的最高层位为符号位)。两个函数都没有引用另一个。

实际上,我需要做的就是替换__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;
}
Run Code Online (Sandbox Code Playgroud)

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

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

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

这似乎与链接时间优化 ( -flto) 有关 - 将其关闭意味着一切正常,但它会增加 8k 的固件大小,使其不再适合可用的闪存!

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

谢谢!

Gor*_*ams 1

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

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

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

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