Intel x86_64汇编,如何从xmm寄存器到int?

for*_*teu 1 assembly x86-64 intel

我怎样才能做到这一点?如果结果将在e*x寄存器中,那将是最好的.

Pet*_*des 5

你已经问了几个琐碎的问题,你可以通过查看C编译器如何做到这一点来回答.从那里,您可以查看它使用的说明,并决定您想要实际使用哪些.(在libm中有大量不同的舍入函数,因此首先选择正确的舍入函数并不总是那么容易).

使用-O3 -ffast-math内联获取最简单的libm函数(因为它不必errno在NaN上设置,或者像这样设置垃圾).

无论如何,编译器输入和输出,来自Godbolt Compiler Explorer上的gcc 5.3:

#include <math.h>

int floor_double(double x) { return (int) floor(x); }
    roundsd xmm0, xmm0, 9
    cvttsd2si       eax, xmm0
    ret

int truncate_double(double x) { return (int)x; }
    cvttsd2si      eax, xmm0
    ret
Run Code Online (Sandbox Code Playgroud)

有关英特尔指令集参考手册pdf的链接,请参阅标签wiki.还有一个从PDF生成的非官方HTML版本.

cvttsd2si截断为零,trunc()而不是像floor()函数那样向-Infinity舍入.

这就是当该指令集可用时floor()编译为SSE4.1 的原因roundsd.(否则它必须摆弄舍入模式,你可以通过删除或更改-marchgodbolt上的选项来看到).


还有转换指令的打包版本,例如CVTTPD2DQ`一次执行2.(或AVX 4).