应该FXAM单精度浮点值的工作?(Should fxam work for single preci

2019-10-24 09:16发布

这个问题从出现为什么isnormal()说的值是正常的,当它是不是?

AC编译器生成以下代码这是为了检测该32位float传递在正常与否:

    flds    24(%esp)
    fxam; fstsw %ax;
    andw    $17664, %ax
    cmpw    $1024, %ax
    sete    %al

(完整的代码可以看到这里 )。

这是代码是否正确? 该程序似乎不正确的行为,说一个数字是正常时,它不是。 我们认为,也许正在检查的数量为双精度常态这里。

Answer 1:

我检查了英特尔的insn的参考手册 ,从链接https://stackoverflow.com/tags/x86/info 。

只有一个版本的fxam指令,它在80bit的寄存器进行操作。 所以,是的,那(低效率)测试80bit的临时常态。 (更高效的将是test $1024, %eax ,而不是掩盖,然后cmp )。

根据这个 , flds本身将引发一个非规格化异常。 我想,这意味着它测试的实际源,转换为80bit的没有结果。 该页面表示,非正规异常将在状态字的位。

英特尔的参考手册没有说任何事情fld设置状态字,只是设置C1标志,并留下C0东西,C2和C3未定义。 它说,你可以得到一个#D FPU异常,如果来源是反规范,但如果来源是80bit的格式,这种情况不会发生。

我不知道,如果状态字会真正得到设置非规格化如果未启用FPU异常。 我不是这方面的专家。 我的阅读此页 (和控制字节)是FPU状态字大部分指令后更新。 如果D位在控制寄存器中设置(它是通过缺省值),则操作数反规范设定的D 状态字位。 这是未设置(揭露),异常会发生。

所以我觉得一个函数来测试一个浮动的非正规会是什么样子:

isdenormalf:
    flds (%rdi)   # sets FPU status based on the input to the 32->80bit conversion
    fstsw %ax
    fstp %st0     # pop
    test $2, %al  # avoid 16 bit ops (%ax), they're slow on Intel
    sete %al   #  or just branch on flags directly if your compiler's smart
    ret

我没有试过,所以它可能是完全伪造的。 在弹出的是我们要保持负载可能是不平凡的内联数据空载/的方式写的。 也许需要一个地址精氨酸,返回浮点(因此它可以在的x87寄存器),和具有与所述状况的输出ARG。

我没有看到,可以检查的指令float在SSE寄存器非标准。

我想我有一个(慢)的方式来测试与SSE4.1或AVX的非正规数ROUNDSS 。 您需要根据输入的符号使用不同的版本。

对于正值:

  • 对回合+inf与非正规数为零
  • 圆往+inf没有非正规数为零。
  • 如果两个舍入结果是不同的,那么非正规数为零了影响(这意味着输入是反规范)

负数需要对要舍-inf ,不+inf ,否则-0.xx将始终向零。 因此,这将有一个分支,二ROUNDSS ES和比较。 在IEEE浮点格式位黑客可能会更快。



文章来源: Should fxam work for single precision floating point values?
标签: assembly x86 x87