The SysVr4 SPARC psABI prescribes 128-bit long double on 32-bit Sparc, and Solaris follows that as do some other OSes. However, clang doesn't support that.
This is not yet complete, but I need guidance in some points and believe it's easier to do so here than in the corresponding Bug 42493
There are several noteworthy issues:
- long double is 128-bit IEEEquad format, but with 64-bit alignment unlike SPARC V9 which uses 128-bit alignment.
- long double is passed and returned by reference, just like structures and unions.
- long double _Complex, a Sun extension not in the psABI, is always returned in registers.
- compiler-rt uses __uint128_t for long double support which isn't available for 32-bit compilations by default. It's currently enabled with -fforce-enable-int128 which gcc doesn't support.
Right now the basic long double support seems to work (need to double-check with GCC's gcc.dg/compat testsuite), but compiling compiler-rt/lib/builtins/divtc3.c fails:
Assertion failed: isRegLoc(), file /vol/llvm/src/llvm-project/local/llvm/include/llvm/CodeGen/CallingConvLower.h, line 150 11 libc.so.1 0xffffffff7edfb158 _assert + 104 12 clang-12 0x00000001038fdf90 llvm::SparcTargetLowering::LowerCall_32(llvm::TargetLowering::CallLoweringInfo&, llvm::SmallVectorImpl<llvm::SDValue>&) const + 11888 13 clang-12 0x00000001038f9010 llvm::SparcTargetLowering::LowerCall(llvm::TargetLowering::CallLoweringInfo&, llvm::SmallVectorImpl<llvm::SDValue>&) const + 60 14 clang-12 0x0000000106062f54 llvm::TargetLowering::LowerCallTo(llvm::TargetLowering::CallLoweringInfo&) const + 7724 15 clang-12 0x0000000106039704 (anonymous namespace)::SelectionDAGLegalize::ExpandLibCall(llvm::RTLIB::Libcall, llvm::SDNode*, bool) + 1896
Besides, something will have to be done about the __uint128_t requirement on 32-bit targets, probably using a union with uint64_t members.
I'm currently lost here and will need some guidance how to proceed.