What is long double on x86-64?

别说谁变了你拦得住时间么 提交于 2019-12-29 06:21:41

问题


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.


回答1:


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.




回答2:


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.




回答3:


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

That's not long double, as you have pointed out. The 64 bit value is just written to the long double after calculation.



来源:https://stackoverflow.com/questions/15176290/what-is-long-double-on-x86-64

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!