should -mno-sse -mno-mmx -msse -mmmx work?

We are using clang for EFI firmware and in general it is a lot like a kernel and we turn off floating point. So the default build flags for our project set -mno-sse -mno-mmx. I'm trying to compile a standard C library that has a few functions with double in it, so I tried to reenable the floating point on the command line for just that package. I thought if you had -mno* and -m the last one wins? It does not seem to work?

~/work/Compiler>cat float.c
double
ErrorInBackEnd ()
{
  return 1.0;
}
~/work/Compiler>clang -mno-sse -mno-mmx -msse -mmmx float.c
fatal error: error in backend: SSE2 register return with SSE2 disabled

Is this a bug? Or functioning as intended

Andrew Fish

<rdar://problem/9694837> SSE register return with SSE disabled

Evan

Hi Andrew-

fatal error: error in backend: SSE2 register return with SSE2 disabled

Is this for 32-bit or 64-bit x86? If it's the latter, the ABI demands
that the return value in this case is in xmm0 - SSE is required.

Alistair

Hi Andrew-

fatal error: error in backend: SSE2 register return with SSE2 disabled

Is this for 32-bit or 64-bit x86?

64-bit x86.

If it's the latter, the ABI demands
that the return value in this case is in xmm0 - SSE is required.

Well -no-sse -mno-mmx works for EFI as it is pre-boot firmware and does not have any floating point C code. We use -no-sse and -mno-mmx code to prevent optimized code gen using these registers for optimizations.

Andrew

Hi Andrew-

Well -no-sse -mno-mmx works for EFI as it is pre-boot firmware and does not have any floating point C code. We use -no-sse and -mno-mmx code to prevent optimized code gen using these registers for optimizations.

Whether it's optimised or not doesn't particularly matter, the x86_64 ABI says that floating-point return values go into SSE registers, so that is where LLVM is required to put them. If you need to avoid these registers, then you may well need to write a separate calling convention for the backend which stores those return values elsewhere (like the x87 fp stack), or just do not return floating-point values.

Alistair

Hi Andrew-

Well -no-sse -mno-mmx works for EFI as it is pre-boot firmware and does not have any floating point C code. We use -no-sse and -mno-mmx code to prevent optimized code gen using these registers for optimizations.

Whether it's optimised or not doesn't particularly matter, the x86_64 ABI says that floating-point return values go into SSE registers, so that is where LLVM is required to put them. If you need to avoid these registers, then you may well need to write a separate calling convention for the backend which stores those return values elsewhere (like the x87 fp stack), or just do not return floating-point values.

Why can't I make a calling convention that states C source code can not use any floating point? At that point -mno-sse and -mno-mmx make sense, and it is a lot easier than adding a new calling convention code gen to the compiler. This is kind of where EFI started from.

Bug, at least in the sense that we weren't gcc-compatible; r134296.
(As a workaround, you could specify -msse2.)

-Eli