How to use gnu gcc flag -mpc32, -mpc64 and -mpc80?

妖精的绣舞 提交于 2021-01-25 20:21:10

问题


I got these GCC flags from the GNU GCC compiler Manual. But when I tried to use those flags (-mpc32, -mpc64 and -mpc80) I couldn't observe the behavior. So I need help on how to use these flags with a sample code.

sample code I tried: test.cpp

#include<stdio.h>
#include<iomanip>
#include<math.h>

int main()
{
    double weight = 1.0f;
    double roiSize = 137.142364501953125f;
    double thresholdValue = 5400.0f;
    double alpha = weight / (roiSize * thresholdValue * thresholdValue);
    std::cout<<std::setprecision(100)<<"alpha = "<<f<<std::endl;
    double test = pow(roiSize, 10);
    std::cout<<std::setprecision(100)<<"alpha = "<<f<<std::endl;
}

Compiling options:

g++ -mpc32 test.cpp
g++ -mpc64 test.cpp
g++ -mpc80 test.cpp

回答1:


The easiest way to test different x87 precisions might be to use long double, which on x86 targets is the 80-bit x87 type. (Except on Windows where long double = double).

Another advantage to long double is that you don't have to compile with -m32 to get it to use x87 at all. (The default for -m64 is -mfpmath=sse; double and float math will be done in XMM registers, at the type width, not widened to x87 internal precision. But long double will always use x87 because SSE/SSE2 can't do 80-bit). TL:DR: on a normal 64-bit system building with gcc -mpc32 foo.c, -mpc32 won't make any difference for math on double variables, because it doesn't even use the legacy x87 FPU.

BTW, this test case also depends on being compiled with the default -O0, otherwise constant propagation at compile time will happen. (And that's unlikely to respect -mpc32.)


137.142364501953125f is a float constant, rounded to float before being used as an initializer for a double. So your starting values are all rounded to the nearest float, despite being stored as double. I assume the division isn't exact, though, so you would still get rounding.


I assume these options just set the x87 precision on startup. MSVC's CRT start code apparently does a similar thing, defaulting to setting 64-bit precision (53-bit mantissa, like double, not full precision). See Bruce Dawson's Intermediate Floating-Point Precision article; one of a series of FP articles. Index in this one.

You can look at the compiler-generate asm to see how it does FP math: using fld / fmul / fstp is x87 and will be affected by the x87 precision set in the x87 control word register.

movsd / mulsd is SSE2 and precision is set by the instruction; no status / control bits can override it. (Only the rounding mode can be changed in MXCSR, and handling of subnormals.)



来源:https://stackoverflow.com/questions/59894562/how-to-use-gnu-gcc-flag-mpc32-mpc64-and-mpc80

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