我正在尝试将大量代码填充到一个相当小的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
?
谢谢!
答案 0 :(得分:0)
我的解决方案(如@artless-noise 所建议的)是使用 -ffreestanding
compiler flag。海湾合作委员会对此有话要说:
断言编译针对独立环境...独立环境是标准库可能不存在的环境,并且程序启动不一定在主环境中。最明显的例子是操作系统内核。
所以它似乎对嵌入式环境很有意义......
这为固件大小增加了大约 250 个字节(大约 0.1%),因为我猜它阻止了编译器利用有关内置运算符的一些假设,但是它确实允许我添加自己的 __aeabi_dsub
实现,总共节省了 1680 字节。