我试图将大量代码塞进一个相当小的ARM微控制器中。我已经在尺寸优化方面做了大量的工作,我已经到了需要双算术的地步,但__aeabi_ddiv
、__aeabi_dadd
和__aeabi_dsub
是整个设备上一些最大的功能。
__aeabi_dadd
和__aeabi_dsub
都是 ~1700 字节,尽管执行基本相同的工作(双精度的最顶部位是符号位(。两个函数都不引用另一个函数。
实际上,我需要做的就是将__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
添加它们.
我知道这可能与IEEE规范不是100%兼容,但在这个平台上,我可以这样做,以便节省>1%的可用闪存。
我的问题是,当我添加该函数时,链接器会抱怨undefined reference to __aeabi_dsub
- 这似乎很奇怪,因为这是定义它的行为导致了错误。
这似乎与链路时间优化(-flto
(有关 - 关闭它意味着一切正常,但是它增加了8k的固件大小,它不再适合可用的闪存!
那么,我需要做什么才能在链接时间优化处于活动状态时替换内置函数__aeabi_dsub
?
谢谢!
我的解决方案(如@artless-noise所建议的那样(是使用-ffreestanding
编译器标志。海湾合作委员会对此有这样的说法:
断言编译针对独立的环境...独立环境是标准库可能不存在的环境,程序启动可能不一定是主要的。最明显的例子是操作系统内核。
因此,无论如何,对于嵌入式环境来说,这似乎很有意义......
这为固件大小增加了~250字节(约0.1%(,因为我想它阻止了编译器利用有关内置运算符的一些假设,但是它确实允许我添加自己的__aeabi_dsub
实现,总共节省了1680字节。