17

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?

Sergey K.
  • 24,894
  • 13
  • 106
  • 174
Dark Falcon
  • 43,592
  • 5
  • 83
  • 98
  • I think this is impossible without changing the code, because the `x86_64` ABI requires `xmm` registers to be present. Maybe some `-Ddouble=mpfr::real` trickery will work, using the `mpfr` library which is required by `gcc` anyway. – Gunther Piez Nov 06 '12 at 17:07
  • As noted, `clang` was able to compile a binary with no references to the floating point instructions or registers. I suppose my real question therefore is if there is a way to make a whole toolchain using something like this. – Dark Falcon Nov 06 '12 at 18:16
  • Was the proposed solution ok? – Sergey K. Nov 13 '12 at 07:48
  • I have not had opportunity to try it yet, unfortunately. I fear it is going to result in the same set of problems I ran into before when trying to use the `-msoft-float` option with GCC: 1. Errors about an x87 register return when x87 instructions are disabled. 2. Undefined symbols for the floating point operations when trying to compile a cross toolchain and no indication of what to change to link properly. I will award the bounty because you definitely put some effort behind the answer. – Dark Falcon Nov 13 '12 at 11:42
  • Have a look at [compiler_rt](http://compiler-rt.llvm.org/) project. – Zinovy Nis Mar 11 '15 at 14:40

1 Answers1

6

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

Community
  • 1
  • 1
Sergey K.
  • 24,894
  • 13
  • 106
  • 174