I work on software for an embedded system which does not have an FPU. I would like to be able to build this software with a software floating point library on my desktop in order to get a more realistic view of performance. Does anyone have any ideas about how to achieve this?
Thus far I have not made much progress with using -msoft-float
with gcc. I am currently looking at using clang. By using the flags -Xclang -msoft-float -Xclang -no-implicit-float
and specifying a library which has implementations of soft-float routines, I am able to get my application to compile. When I try to run it, it always segfaults. As best I can tell, this is because the libraries on which this program depends were not compiled with soft-float. The app depends on gtk, sqlite, expat, gcrypt, a number of internal libraries, and libc.
I would like to try to figure out how to build a complete build environment with soft-float support. I tried uclibc's buildroot and setting CC
and CXX
to clang's binaries, but this did not work due to the requirements for compiling the gcc toolchain (things such as autotools complaining about the compiler version being incorrect). Since I would like to use clang as the compiler in the new buildroot (in order to have soft-float support), I don't see a pressing need to build gcc. Is it possible to do this without gcc?
GCC can not do it out-of-box without some additional libraries. Basically, -msoft-float
just generate calls for floating point libraries but the required libraries are not part of GCC.
To link the soft-fp
libraries you can use the switch -lsoft-fp
.
X86_64 architecture contains SSE extensions, so the compiler will try to generate SSE-code for basic operations like + - * /. We will use -mno-sse
switch suppress this unauthorized behavior.
It may look as follows:
gcc -g -msoft-float -mno-sse -m64 -lsoft-fp
For the code:
int main()
{
float a = 10;
float b = 20;
float c = a * b;
return 0;
}
The resulting assembly will be:
.file "12.cpp"
.def __main; .scl 2; .type 32; .endef
.def __mulsf3; .scl 2; .type 32; .endef
.text
.globl main
.def main; .scl 2; .type 32; .endef
.seh_proc main
main:
pushq %rbp
.seh_pushreg %rbp
movq %rsp, %rbp
subq $48, %rsp
.seh_stackalloc 48
.seh_setframe %rbp, 48
.seh_endprologue
call __main
movl .LC0(%rip), %eax
movl %eax, -4(%rbp)
movl .LC1(%rip), %eax
movl %eax, -8(%rbp)
movl -8(%rbp), %edx
movl -4(%rbp), %ecx
call __mulsf3
movl %eax, -12(%rbp)
movl $0, %eax
addq $48, %rsp
popq %rbp
ret
.seh_endproc
.section .rdata,"dr"
.align 4
.LC0:
.long 1092616192
.align 4
.LC1:
.long 1101004800
.ident "GCC: (GNU) 4.8.0 20120624 (experimental)"
No SSE instructions were generated. Note the call to __mulsf3
.
Some interesting ideas can be found in this question: Using software floating point on x86 linux