How can I tell the linker/compiler not to use memset/memcpy function which use FPU registers?
For example: SCIOPTA allows to limit the use of the FPU for certain tasks (to improve task-switching). Tasks without FPU may not use FPU registers. But the compiler/linker uses optimized versions of memset() which results in an exception.
I tried to compile C files with --fpu none, but this produces link-timer errors.
Of course, if I use the FPU I must expect that for example printf() uses FPU registers. But I do not expect that the compiler uses FPU registers for things like memset(). Since parts of the software are allowed (=> RTOS configuration) to use the FPU and some not, I need the choice. Clearly, I cannot use printf() in a task which is not allowed to use the FPU. If so, it is _my_ fault.
Of course, if I use the FPU I must expect that for example printf() uses FPU registers.
But I do not expect that the compiler uses FPU registers for things like memset().
Since parts of the software are allowed (=> RTOS configuration) to use the FPU and some not, I need the choice.
Clearly, I cannot use printf() in a task which is not allowed to use the FPU. If so, it is _my_ fault.
Based on that comment, I'm not entirely sure I understand your use case.
I've seen things like Android builds where every application has been built (with gcc..) for VFPv3 floating point, and the only floating point usage for hundreds of application binaries like file and filesystem utilities, system daemons, really boring code with no reason to use floating point and doesn't do any heavy lifting or data movement or processing, is for register spilling (freeing up integer registers by using the floating point register file for temporary storage instead of the stack). This is obviously where the context switch overheard -- and power consumption of course -- would be adversely affected, and in a vast majority of the cases the register spilling is pointless because the functions that end up using it don't even use enough of the volatile register file to make it worthwhile. It makes a lot of sense, there, to identify which applications really need floating point and just turn it off completely in the build for those individual applications.
Per Stephen Theobald's advice, the ARM compiler works on two things to decide whether it will generate FP instructions -- the "no_allow_fpdata_in_fpregs" option affects code generation by the compiler, including things like register spilling. The "cpu" and "fpu" options affect which ARM C Library is linked in.
So by default you're seeing a sort of mix of both worlds -- a totally only-integer-requiring application which the compiler refrains from using FP register file, but has an optimized ARM C library which uses floating point registers.
Now, in your description, you're saying you want to build an application which does not have any FP instructions in it at all to save on context switch storage space and time to context switch -- the solution there is to build the application in question with --fpu=none or similar as Stephen suggested. If you use printf() and you use a floating point format string argument, it will use a softfloat variant of the library to get that working and never use a floating point register, so your context switch time and stack space would be preserved. However how much benefit do you really get here? The context switch time is minuscule, usually, compared to a large memcpy or memset. You would rather these workhorse functions execute quickly..
Back to your comment, in terms of building an application that can use floating point instructions (printf %d or a math library function like cosf() for example) but you do not want it to use the optimized ARM C library functions that would otherwise not use the floating point unit, this is pointless -- you'd end up with the expensive context switch anyway the moment one of those FP registers was used.
I think your question has been answered (as above, and previously by Stephen), so is there a particular issue here with building your application, still, if you disable floating point completely (cpu, fpu)?
Ta,
Matt
Mat,
the point is our RTOS allows users to disable FPU usage for certain processes (mostly for all but a few) to save context-switch time and stack space. The user is aware that they cannot use printf() or floating point mathematics in these tasks.
_But_ he is certainly not aware that the compiler uses FPU registers for a memcpy(). So the -no_allow.. option is surely something he needs to apply when compiling those processes. But since 99% of our customers have a single binary, they must link in the FPU version of the library since they use math functions in a few tasks.So I see the only way is to remove the optimized function from the library.
Cheers,
42Bastian
Perhaps a possible solution would be to write tiny wrappers for memcpy, memmove and memset.
Each wrapper checks whether or not the current task is allowed to use FPU registers.
-It could then call the right memcpy / memmove and memset, depending on the flag.