# 3.11.5 在浮点代码中使用位级操作

有时,我们会发现 GCC 生成的代码会在 XMM 寄存器上执行位级操作,得到有用的浮点结果。图 3-50 展示了一些相关的指令,类似于它们在通用寄存器上对应的操作。这些操作都作用于封装好的数据,即它们更新整个目的 XMM 寄存器,对两个源寄存器的所有位都实施指定的位级操作。和前面一样,我们只对标量数据感兴趣,只想了解这些指令对目的寄存器的低 4 或 8 字节的影响。从下面的例子中可以看出,运用这些操作通常可以简单方便地操作浮点数。

单精度 双精度 效果 描述
vxorps vxorpd D ← S₂ ^ S₁ 位级异或(EXCLUSIVE-OR)
vandps vandpd D ← S₂ & S₁ 位级与(AND)

图 3-50 对封装数据的位级操作(这些指令对一个 XMM 寄存器中的所有 128 位进行布尔操作)

练习题 3.56 考虑下面的 C 函数,其中 EXPR 是用 #define 定义的宏:

double simplefun(double x) {
    return EXPR(x);
}

下面,我们给出了为不同的 EXPR 定义生成的 AVX2 代码,其中,x 的值保存在 %xmm0 中。这些代码都对应于某些对浮点数值有用的操作。确定这些操作都是什么。要理解从内存中取出的常数字的位模式才能找出答案。

A.

1  vmovsd .LC1(%rip), %xmm1
2  vandpd %xmm1, %xmm0, %xmm0
3  .LC1:
4      .long 4294967295
5      .long 2147483647
6      .long 0
7      .long 0

B.

1  vxorpd %xmm0, %xmm0, %xmm0

C.

1  vmovsd .LC2(%rip), %xmm1
2  vxorpd %xmm1, %xmm0, %xmm0
3  .LC2:
4      .long 0
5      .long -2147483648
6      .long 0
7      .long 0