Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is long double on x86-64?

Someone told me that:

Under x86-64, FP arithmetic is done with SSE, and therefore long double is 64 bits.

But in the x86-64 ABI it says that:

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

See: amd64-abi.pdf

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

So I'm confused, how is long double 64 bit? I thought it is an 80-bit representation.

like image 687
Andrew Tomazos Avatar asked Mar 02 '13 15:03

Andrew Tomazos


2 Answers

Under x86-64, FP arithmetic is done with SSE, and therefore long double is 64 bits.

That's what usually happens under x86-64 (where the presence of SSE instructions is guaranteed), but the program is still free to use x87, to which the compiler can resort when you use a long double.

You can have confirmation of this by compiling a program like this with 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 assembly output, I find mulsd xmm1, xmm0 for the double product and mulss xmm0, xmm2 for the float product (both SSE instructions), but fmulp st(1), st (x87 instruction) for the long double product.

So, it's confirmed, the compiler uses SSE when it can, but still allows 80-bit precision computations via the old x87 instruction set.


Notice that this is compiler-specific - some compilers (e.g. VC++) always ignored 80-bit precision types and just treated long double as a synonym of double.

On the other hand, since the x86-64 System V ABI (adopted on Linux) mandates that long double is 80 bit, the only way for a compiler to perform computations using all the available precision of the type is to use the x87 instructions.

like image 135
Matteo Italia Avatar answered Sep 23 '22 07:09

Matteo Italia


The AMD ABI cannot actually compel what the C long double type is, because it does not have the jurisdiction/authority to do so. Each C implementation can make its own specification of what the types are, subject to the C standard (if the C implementation is conforming to the standard), and each C implementation can choose whether or not to conform to the AMD ABI.

This means you cannot simply ask “What is long double on x86-64?” You must ask what is long double in a specific C implementation. That means specifying a particular C compiler, version, and switches used to compile. (A compiler might have a switch for which one setting makes long double a 64-bit binary IEEE 754-floating-point object and another setting makes long double the 80-bit Intel floating-point object. Technically, each different combination of compiler, version, and switches is a distinct C implementation.)

A compiler that implements long double as a 64-bit binary IEEE-754 floating-point object simply passes them as what the AMD ABI calls double; it never passes them as what the ABI calls long double. In doing so, this aspect of the compiler would be compatible only with other software that treats long double similarly.

like image 45
Eric Postpischil Avatar answered Sep 23 '22 07:09

Eric Postpischil