I'm trying to cram a lot of code into a reasonably small ARM microcontroller. I've done a massive amount of work on size optimisation already, and I'm down to the point where I need double arithmetic, but __aeabi_ddiv
, __aeabi_dadd
and __aeabi_dsub
are some of the biggest functions on the whole device.
Both __aeabi_dadd
and __aeabi_dsub
are ~1700 bytes each, despite doing basically the same job (the very top bit of doubles is the sign bit). Neither function references the other one.
Realistically all I need to do is replace __aeabi_dsub
with:
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;
}
and I'd save ~1700 bytes - so flipping the sign of the second argument, then adding them using __aeabi_dadd
.
I'm aware that this may not be 100% compatible with the IEEE spec, but on this platform I'm ok with that in order to save > 1% of my available flash.
My problem is that when I add that function, the linker complains with undefined reference to __aeabi_dsub
- which seems strange given that it's the act of defining it that causes the error.
This appears to be related to link time optimisation (-flto
) - turning it off means it all works perfectly, however it adds 8k to the firmware size to it no longer fits in available flash!
So what do I need to do to be able to replace the built-in function __aeabi_dsub
when link time optimisation is active?
thanks!
-Os
yet? Really, before hacking std libraries, better try optimizing the code. Also if your processor has an FPU you can utilize it and get rid of these functions. – Ankarasin
with slower but smaller versions (which works fine). This question is about GCC, FLTO and built-in functions, @toohonestforthissite your personal views on language choice shouldn't come into it. The build is for the BBC micro:bit, a device for school children. IMO the vast majority of 10 year olds aren't going to get far with interrupts, pointers, and Nordic's Bluetooth softdevice. – Mooring-ffreestanding
? This will often eliminate the issue. Please provide the gcc version as well. – Ibrahim-ffreestanding
actually added ~250 bytes to the firmware size (I guess some of the assumptions about builtins were broken), but adding mydsub
code saved 1680 bytes, so it's still a very clear win – Mooring-ffreestanding
is not the only solution. See: Static libraries with lto for some more background. Either-lc
or-lgcc
that you link with may not be LTO friendly. I doubt your question will be reopened; most people can not understand you (or were too distracted by what you are trying to accomplish); which you should take as a complement. I used nsjs years ago and it was under 100k at that time. – Ibrahim