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.
For ARM compiler you could try --no_allow_fpreg_for_nonfpdata
--no_allow_fpreg_for_nonfpdata
See ARM Information Center
See
ARM Information Center
Hi Joseph,
that'll be the option I was looking for. Only it does not work. At least not with 5.04.
My compile options:
CPUFLAGS = --cpu cortex-a8 --apcs=/interwork --thumb
CFLAGS += $(CPUFLAGS) --debug --diag_suppress=550 --c99 --no_inline
CFLAGS += --diag_suppress=9933
CFLAGS += --no_allow_fpreg_for_nonfpdata
My code uses memset(...,0,...). _memset() in the Library checks if the destination is dividable by 4 and then jumps to memset_w which uses FPU registers.
Hi,
I guess the FP instructions is inside the C runtime library, not the compiler generated code. Is that correct?
I guess the option --no_allow_fpreg_for_nonfpdata only affects the compiler and there isn’t a switch to force C runtime code to use a different behavior.
Sorry that I don’t have a solution for you right now.
Regards,
Joseph
yes, it is the memset in the standard C library. Guess there should be a no_allow_fpreg_for_nonfpdata version of the library.
(Btw. GCC does the same and tries to be "smart" )
THX for your time.
Then the solution will be to use -no_allow_fpreg_for_nonfpdata while compiling the runtime library (if using GCC, that is).
I use GCC myself, and when building my toolchain, one of the steps is to generate multiple libraries; one for each CPU type; for instance, there's no Cortex-M0 with FPU, thus it's not necessary to generate a runtime library with FPU support.
Could be a solution. But isn't.
For one, GCC does not have that or similar option (at least 4.9.3 2014 Q4 from launchpad), nor does DS-5 (professional) come with library sources.
And the problem is not no-FPU or FPU. The problem is, that the user decides where to use the FPU and where not.
The armcc option says it all: FPU registers only for FPU operation.
If I compile a C program with float operations, the compiler shall use of course the FPU if activated per command line.
And of course mixing soft-FPU code and hard-FPU code is difficult and rather seldom. But why not? At least as long no higher functions like sin() is used.
In my opinion, either the linker should be able to link FPU compiled files against a non-FPU library _or_ provide FPU clean standard libraries.
The linker should never be allowed to modify the library, which is linked. Thus you must link with the correct library; this is your responsibility.
That means you will need a library, which contains code that does not use the FPU registers, if you don't want your code to use FPU registers.
I've used GCC 4.9 for more than a year now, and I have multiple libraries for each Cortex-M architecture and ARM7TDMI.
So I can choose whether or not I want to use the FPU registers on Cortex-M4 by supplying a switch on the command-line for GCC and for the linker.
The linker will chose the correct library, depending on my command-line switches; eg. if I built a library using -mcpu=cortex-m4 and -mtune=cortex-m3, and the switches I provide for the linker is exactly that, then this library will be linked.
I'm not sure whether launchpad's GCC is built this way these days; I think it was earlier.
If you want to solve the problem here and now, you could write your own substitution for memset and memcpy. Make sure the link-order is correct, so your library will be searched first. One problem with using this solution is that you might not catch all the library functions, which are using FPU-registers right away.
Jens,
I think you are missing the point.
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.
So what is needed is that the linker has an option to choose the right library or I need the choice to build my own runtime library and setting the -no_allow ... option. But as I wrote, no library sources in DS-5 installation (maybe I need the ultra license).
Neither works in GCC and DS-5/MDK. I think IAR does a better job here.
I probably misunderstood the problem as you wrote.
Is the memset code you're speaking about, generated on-the-fly ?
Eg. GCC generates both memcpy and memset code, if the block to set/copy is less than four 32-bit words.
I know GCC does optimize short memset/memcpy and I had to fight this on PowerPC. But so far I had no problem with GCC and ARM.
The problem is with DS-5/MDK and memset() is in the library.
PowerPC, Atari ... we have a lot in common.
Unfortunately my only option is running GCC, so I know nothing about DS-5/MDK.
If we're lucky, maybe sellis or johannesbauer will put in a word or two about this.
View all questions in Arm Development Studio forum