Data type real not implemented correctly on architectures different from x86 / x86_64
TDPL states that real is the floating point type "largest in hardware". On x86 / x86_64 this is 80bit. On PPC/PPC64 there are only 32bit and 64bit floating point types. Such real is equal to double. There is also a long double type with 128bit but this is a software implementation using 2 double values.
The LDC IR code gets it right. Sadly, the front end uses hard-coded constants for floating point attributes like mant_dig. This has the following bad effects on PPC64:
- LDC chooses double as the LLVM type (64bit)
- the frontend uses the compile time constants (default with gcc: 128bit; default with xlC: 64bit)
- modules like
std.mathdo not compile (no support fordoubledoubletype with 106bit mantissa)
A quick fix for a native compiler is to change the definitions in longdouble.h.
Clearly, this prevents cross-compiling floating point code across different cpu architectures.
With commit 2898e5cac36af39ee3b3266b8a665f1e7b74002e I map datatype real to PPC 128bit doubledouble. Native compilation works now but cross-compiling is still broken.
To enable true cross compilation we have to create a real_t replacement. My first thought is to create a thin wrapper around llvm::APFloat.
The main remaining obstacle here is a software real_t type for hosts with a native real (exception for Windows hosts: x87) with less precision than the target. The constants in dmd.root.ctfloat should be good for all formats; the real format selection still needs to be adapted for exotic targets (e.g., IBM z, and PowerPC with their various formats), by someone who knows or reads up on these archs.