汇编语言中与Ceil、Floor等价的指令

3

ceil和floor在x86中的对应操作是什么? 我无法通过谷歌找到相应的指令。 尽管最好只使用一个指令,但对应操作不一定只有一个指令。


这个回答解决了你的问题吗?在x86汇编中使用Math.h库函数? - Z4-tier
谢谢回复。但是我正在寻找一些FPU可以处理的东西,例如它具有截断和舍入浮点数的功能。我正在寻找类似的东西。 - Apoorv Jain
你使用哪个FPU?x87 FPU还是SSE FPU?答案会根据你想要使用哪个FPU而有所不同。 - fuz
我正在使用x87 FPU。 - Apoorv Jain
1个回答

5
一条指令的 floor/ceil 只在 SSE4.1 中可用,使用 roundsd/roundpd,仅适用于 XMM 而非传统的 x87。
x87 中,您设置当前舍入模式,然后使用 frndint。(http://www.ray.masmcode.com/tutorial/fpuchap1.htm 显示了 x87 控制字中的 RC 位)。可用的舍入模式为:最近偶数(默认),朝正无穷(ceil),朝负无穷(floor)和朝零(trunc)。
完成后不要忘记将舍入模式设回原值。
显然,在某些 CPU 上,frndint 是比较慢的(https://agner.org/optimize)。在适当设置舍入模式的情况下,将其转换为整数并再次转换回去可能会更快,可使用 fistp/fild。但是,这仅适用于可以表示为有符号 64 位整数的 FP 值(假设您使用 qword 存储器操作数)。您可以添加/减去适当的魔法数字(使值变得非常大以强制舍入)。同样,这可能需要设置舍入模式。
当然,如果您想要 (int)floor(x),那么一定要使用所需的舍入模式设置 fistp
使用 SSE3,您可以使用 fisttp 向零截断(它是为了加速 C 浮点数->整数转换而添加的,在仍然希望使用传统 x87 的代码中使用 SSE)。 floor == trunc 对于非负值而言,因此您可以利用有效的 fisttp 或 SSE XMM 截断。
在 SSE4.1 中,对于 XMM 寄存器中的标量 double,您将使用 roundsd 将其四舍五入为最接近的整数值 double,并指定您选择的舍入模式立即操作数。(不是转换,只是类似于 frndint 的双精度->双精度舍入,因此适用于任何值)。可用打包和标量单精度和双精度版本。

SSE4.1提供了最好的方法来使用roundsd + cvtsd2si实现(int)floor(x)。 如果您知道您的值是非负的,您可以直接使用SSE2的cvttsd2si。请注意, "truncate" 的额外t。(对于单精度或使用cvtpd2dq的打包SIMD也是如此。)


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接