What doubles on x86-64 for a long time?

Someone told me that:

In x86-64, FP arithmetic is done using SSE, so long double is 64 bits.

But ABI x86-64 says that:

C type | sizeof | alignment | AMD64 Architecture long double | 16 | 16 | 80-bit extended (IEEE-754) 

See: amd64-abi.pdf

and gcc says that sizeof(long double) is 16 and gives FLT_DBL = 1.79769e+308 and FLT_LDBL = 1.18973e+4932

So I'm confused how long double 64 bit? I thought this was an 80 bit representation.

+4
source share
3 answers

In x86-64, FP arithmetic is done using SSE, so long double is 64 bits.

What usually happens with x86-64 (where SSE instructions are guaranteed), but the program can still use x87, which the compiler can use when using long double .

You can have confirmation of this by compiling such a program using g++ on Linux:

 #include <iostream> #include <cstdlib> #include <ctime> int main() { std::srand(std::time(NULL)); float f1=rand(), f2=rand(); double d1=rand(), d2=rand(); long double l1=rand(), l2=rand(); std::cout<<f1*f2<<" "<<d1*d2<<" "<<l1*l2<<std::endl; return 0; } 

In the build output, I find mulsd xmm1, xmm0 for product double and mulss xmm0, xmm2 for product float (both SSE instructions), but fmulp st(1), st (instruction x87) for product long double .

So, this confirms that the compiler uses SSE whenever it can, but still allows 80-bit precision calculations through the old x87 instruction set.


Please note: this is a compiler - some compilers (for example, VC ++) always ignore 80-bit precision types and simply treat long double as a synonym for double .

On the other hand, since the x86-64 System V ABI (adopted by Linux) requires a long double 80 bits, the only way for the compiler to perform calculations using all available type precision is to use the x87 instructions.

+7
source

AMD ABI cannot actually force type C long double because it does not have jurisdiction / authority for this. Each C implementation can make its own type specification, taking into account the C standard (if the C implementation conforms to the standard), and each C implementation can choose whether to comply with AMD ABI.

This means that you cannot just ask: "What is a long double on x86-64?" You should ask what a long double in a specific implementation of C. This means specifying the specific compiler, version, and switches used to compile. (The compiler may have a switch for which one parameter sets the long double IEEE 754 64-bit binary floating-point object, and the other parameter makes the long double 80-bit Intel floating-point object. Technically, every combination of compiler, version, and switches is separate implementation C).

A compiler that implements long double as a 64-bit IEEE-754 floating-point binary simply passes them as if AMD ABI calls double ; it never passes them how ABI calls a long double . At the same time, this aspect of the compiler will be compatible only with other software, which similarly applies to long double .

+5
source

The SSE calculation is double precision, and the intermediate representation is 64 bits.

This is not a long double , as you indicated. A 64-bit value is simply written to a long double after calculation.

0
source

All Articles