根据What's A Creel video, "Modern x64 Assembly 4: Data Types" (link to the slide)视频中的一张幻灯片,
注意:real10仅与x87 FPU一起使用,现在在很大程度上被忽略但提供了惊人的精确度!
他说,
“Real10仅用于x87浮点单元。[...]有趣的是它为你提供了大量的精确度提升。你可以通过这种增益获得性能提升,因为你不能使用带有SSE,打包,SIMD样式指令的real10。但是,它有点有趣,因为如果你想要更高的精度,你可以使用x87风格的FPU。现在它几乎从未使用过。“
但是,我在谷歌上搜索GCC supports __float80
and __float128
。
GCC中的__float80
是否计算在x87上?或者像其他浮动操作一样使用SIMD?那么__float128
呢?
答案 0 :(得分:1)
GCC docs for Additional Floating Types:
ISO / IEC TS 18661-3:2015为其他浮动类型
定义了C支持_Floatn
和_Floatnx
... GCC目前在任何系统上都不支持_Float128x。
我认为_Float128x
是IEEE binary128,即具有巨大指数范围的真正128位浮点数。请参阅http://www.open-std.org/jtc1/sc22/wg14/www/docs/n1691.pdf。
__float80
显然是x87 10字节类型。在x86-64 SysV ABI中,它与long double
相同;在ABI中都有16字节对齐。
__ float80在i386,x86_64和IA-64目标上可用,并支持80位(XFmode)浮点类型。它是这些目标上类型名称_Float64x的别名。
我认为__float128
是使用SSE2的扩展精度类型,可能是“双倍”格式,尾数宽度的两倍,但指数限制与64位double
相同。 (即指数范围小于__float80
)
在i386,x86_64和...上,__ fllo128是_Float128的别名
这些可能与gcc为您提供的{double}加倍__float128
。或者也许它是一个纯软件浮点128位
Godbolt compiler explorer对于gcc7.3 -O3(与gcc4.6相同,显然这些类型不是新的)
//long double add_ld(long double x) { return x+x; } // same as __float80
__float80 add80(__float80 x) { return x+x; }
fld TBYTE PTR [rsp+8] # arg on the stack
fadd st, st(0)
ret # and returned in st(0)
__float128 add128(__float128 x) { return x+x; }
# IDK why not movapd or better movaps, silly compiler
movdqa xmm1, xmm0 # x arg in xmm0
sub rsp, 8 # align the stack
call __addtf3 # args in xmm0, xmm1
add rsp, 8
ret # return value in xmm0, I assume
int size80 = sizeof(__float80); // 16
int sizeld = sizeof(long double); // 16
int size128 = sizeof(__float128); // 16
因此gcc调用了一个用于__float128
加法的libgcc函数,而不是内联指数的增量或类似的任何聪明的东西。
答案 1 :(得分:0)
我找到了answer here
__float80
可用于i386,x86_64和IA-64目标,并支持80位(XFmode
)浮点类型。它是这些目标上类型名称_Float64x的别名。
查看了XFmode
,
“扩展浮动”模式表示IEEE扩展浮点数。该模式只有80个有意义的位(10个字节)。一些处理器要求将这些数字填充到十二个字节,其他处理器填充到十六个字节;此模式用于。
仍然不完全相信,我编写了一些简单的
int main () {
__float80 a = 1.445839898;
return 1;
}
使用Radare我把它倾倒了,
0x00000652 db2dc8000000 fld xword [0x00000720]
0x00000658 db7df0 fstp xword [local_10h]
我相信fld
,fstp
是x87
指令集的一部分。所以它被用于__float80
10字节浮点数,但是在__float128
,我得到了
0x000005fe 660f6f05aa00. movdqa xmm0, xmmword [0x000006b0]
0x00000606 0f2945f0 movaps xmmword [local_10h], xmm0
所以我们在这里可以看到我们正在使用SIMD xmmword