是的x87 FILD和SSE指令CVTSI2SD的有符号当量? [英] Are there unsigned equivalents of the x87 FILD and SSE CVTSI2SD instructions?

查看:518
本文介绍了是的x87 FILD和SSE指令CVTSI2SD的有符号当量?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现C'S UINT -to相当于 - 双击投在GHC Haskell编译。我们已经实施 INT -to - 双击使用 FILD CVTSI2SD 。有这些操作的无符号的版本,或者我应该转换(从而失去范围)前零出 UINT 的最高位?

I want to implement the equivalent of C's uint-to-double cast in the GHC Haskell compiler. We already implement int-to-double using FILD or CVTSI2SD. Is there unsigned versions of these operations or am I supposed to zero out the highest bit of the uint before the conversion (thus losing range)?

推荐答案

您可以利用一些IEEE双精度格式,跨preT无符号值的尾数部分的性能,同时增加了一些精心打造的指数

You can exploit some of the properties of the IEEE double format and interpret the unsigned value as part of the mantissa, while adding some carefully crafted exponent.

Bits 63 62-52     51-0
     S  Exp       Mantissa
     0  1075      20 bits 0, followed by your unsigned int

1075来自IEEE指数偏差(1023)双打和52位为你的尾数转向量。请注意,有一个隐含的1引领尾数,需要将在后面减去

The 1075 comes from the IEEE exponent bias (1023) for doubles and a "shift" amount of 52 bits for your mantissa. Note that there is a implicit "1" leading the mantissa, which needs to be subtracted later.

所以:

double uint32_to_double(uint32_t x) {
    uint64_t xx = x;
    xx += 1075ULL << 52;         // add the exponent
    double d = *(double*)&xx;    // or use a union to convert
    return d - (1ULL << 52);     // 2 ^^ 52
}

如果您不必在平台上的原生64位SSE使用该整数步骤的版本可能是有益的,但​​是这取决于当然的。

If you don't have native 64 bit on you platform a version using SSE for the integer steps might be beneficial, but that depends of course.

在我的平台上,这编译为

On my platform this compiles to

0000000000000000 <uint32_to_double>:
   0:   48 b8 00 00 00 00 00    movabs $0x4330000000000000,%rax
   7:   00 30 43 
   a:   89 ff                   mov    %edi,%edi
   c:   48 01 f8                add    %rdi,%rax
   f:   c4 e1 f9 6e c0          vmovq  %rax,%xmm0
  14:   c5 fb 5c 05 00 00 00    vsubsd 0x0(%rip),%xmm0,%xmm0 
  1b:   00 
  1c:   c3                      retq

这看起来pretty不错。在为0x0(%RIP)是神奇的双重恒定的,如果内联像高32位归零,并不断重装会消失的一些指令。

which looks pretty good. The 0x0(%rip) is the magic double constant, and if inlined some instructions like the upper 32 bit zeroing and the constant reload will vanish.

这篇关于是的x87 FILD和SSE指令CVTSI2SD的有符号当量?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆