英特尔x86_64的组装,如何落地双从XMM寄存器为int? [英] Intel x86_64 assembly, how to floor double from xmm register to int?

查看:310
本文介绍了英特尔x86_64的组装,如何落地双从XMM寄存器为int?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我怎样才能做到这一点?这将是最好的,如果结果将是E * X寄存器。

How can I do that? It would be best if result will be in e*x register.

推荐答案

您已经问过,你可以通过看C编译器是如何做的接听几个琐碎的问题。从那里,你可以看一下它使用的指令,并决定要实际使用哪些。 (有大约在libm中数不胜数不同的舍入的功能,所以在第一时间挑选合适的人并不容易)。

You've asked several trivial questions which you could answer by just looking at how a C compiler does it. From there, you can look up the instructions it used, and decide which ones you want to actually use. (There are about a zillion different rounding functions in libm, so picking the right one in the first place isn't always easy).

使用 -O3 -ffast-数学内联得到最简单的libm函数(因为它不具有潜在的设置错误号上NAN或垃圾一样的)。

Using -O3 -ffast-math gets most simple libm functions inlined (since it doesn't have to potentially set errno on NaN, or crap like that).

反正编译的输入和输出,从<一href=\"http://gcc.godbolt.org/#compilers:!((compiler:clang380,options:'-xc+-std%3Dgnu11+-O3+-Wall+-Wextra+-fverbose-asm+-march%3Dhaswell+-mno-avx+-ffast-math',source:'%23include+%3Cmath.h%3E%0A%0Aint+floor_double(double+x)+%7B+return+(int)+floor(x)%3B+%7D%0A%0Aint+truncate_double(double+x)+%7B+return+(int)+(x)%3B+%7D')),filterAsm:(commentOnly:!t,directives:!t,intel:!t,labels:!t),version:3\"相对=nofollow>在Godbolt编译器资源管理器GCC 5.3:

Anyway, compiler input and output, from 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

查看 86 标签维基英特尔指令集的参考手册PDF。还有一个非官方的HTML版本从PDF 产生的。

See the x86 tag wiki for links to Intel's instruction set reference manual pdf. There's also an unofficial HTML version generated from the PDF.

cvttsd2si 截断向零 TRUNC() ,而不是朝着负无穷大的舍入像的 地板()功能

cvttsd2si truncates towards zero, like trunc(), instead of rounding towards -Infinity like the floor() function.

这就是为什么地板()编译为SSE4.1 roundsd 时的指令集是可用的。 (否则它与舍入模式摆弄,你可以通过删除或更改对godbolt的 -march 选项见)。

That's why floor() compiles to SSE4.1 roundsd when that instruction set is available. (Otherwise it has to fiddle with the rounding mode, as you can see by removing or changing the -march option on godbolt).

有也挤满的转换指令的版本,如 CVTTPD2DQ` 做2立刻。 (或4 AVX)。

There are also packed versions of the conversion instructions, like CVTTPD2DQ` to do 2 at once. (Or 4 with AVX).

这篇关于英特尔x86_64的组装,如何落地双从XMM寄存器为int?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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