Skip to content

Conversation

@mrexodia
Copy link
Contributor

@mrexodia mrexodia commented Nov 24, 2025

This fixes a longstanding issue where the 80-bit floats would not be passed correctly to the memory_f80 functions.

After #723 the semantics are compiled as x86_64-none-elf with -ffreestanding (fully OS independent) and -mlong-double-80 to support 80-bit floats in the generated IR. The idea is that the instruction semantics themselves are 'pure' LLVM IR that we can freely retarget for our purposes without having to worry about ABI changes. This works because the State structure is packed and we use uintXX_t in the helper signatures.

The native_float80_t appears to have been designed to convert between struct float80_t { uint8_t data[10]; } and whatever is the widest long double available on the target platform. Unfortunately this type was used in the intrinsics:

[[gnu::used]] extern Memory *__remill_read_memory_f80(Memory *, addr_t,
                                                      native_float80_t &);
[[gnu::used]] extern Memory *
__remill_write_memory_f80(Memory *, addr_t, const native_float80_t &);

This causes an ABI break of sorts, because the intrinsics might be targeting Windows (MSVC) which does not support long double. We should instead pass float80_t, which has a known layout across all target triples and the intrinsic implementation for that platform is responsible for handling conversions (using native_float80_t if they desire).

In practice this likely would not matter much, since the higher 2 bytes are for additional precision and they do not represent any 'meaningful' bits of the float. If your platform does not support 80-bit floats it's just not the same as native x87 operations, but with this change you can (in theory) use a softfloat implementation to get perfect semantics.

@mrexodia mrexodia marked this pull request as ready for review November 24, 2025 12:55
Copy link
Collaborator

@kyle-elliott-tob kyle-elliott-tob left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great catch, and thank you for extending the test cases as well. Just as a side note, was this behavior only observed with MSVC or was it also present when compiling with clang-cl?

@mrexodia
Copy link
Contributor Author

It would apply to MSVC/clang-cl/clang on Windows, since long double isn't supported when targeting Windows at all.

@kyle-elliott-tob kyle-elliott-tob merged commit 9816ccc into lifting-bits:master Nov 24, 2025
15 checks passed
@mrexodia mrexodia deleted the float80-bug branch November 24, 2025 19:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants