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

时间:2016-06-01 14:42:40

标签: assembly x86-64 intel

我该怎么做?如果结果将在e * x寄存器中,那将是最好的。

2 个答案:

答案 0 :(得分:5)

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

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

无论如何,编译器输入和输出来自gcc 5.3 on the Godbolt Compiler Explorer

#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

有关英特尔指令集参考手册pdf的链接,请参阅标记wiki。还有一个unofficial HTML version从PDF生成。

cvttsd2si truncates towards zero,与trunc()一样,而不是像floor() function一样向-Infinity舍入。

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

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

答案 1 :(得分:0)

使用CVTTPD2DQ—Convert with Truncation Packed Double-Precision FP Values to Packed Dword Integers至地板双打。

CVTTPD2DQ在XMM注册表中将两个double发送到两个int

相应的 Intel C / C ++ Compiler Intrinsic

____m128i _mm_cvttpd_epi32(__m128d a)

要将结果放到GPR(通用寄存器),如EAX,您可以使用以下说明:

CVTTPD2DQ xmm0, xmm1 ; XMM1 is the source of doubles
movd eax, xmm0       ; extracts int(0) from XMM0 to EAX
pextrd ecx, xmm0, 1  ; extracts int(1) from XMM0 to ECX