相当于 Ceil , Floor 的汇编语言

Apo*_*ain 3 x86 assembly floor ceil x87

ceil、floor 在 x86 中的等价物是什么?我无法特别谷歌相应的说明。等效指令不一定是一条指令,尽管一条指令是优选的。

Pet*_*des 5

单指令下限/上限仅适用于 SSE4.1 roundsd/ roundpd,并且仅适用于 XMM,不适用于传统 x87。


对于 x87,您可以设置当前舍入模式,然后使用frndint. (http://www.ray.masmcode.com/tutorial/fpuchap1.htm显示了 RC 位在 x87 控制字中的位置)。可用的舍入模式有最近偶数(默认)、朝向 +Inf(ceil)、朝向 -Inf(floor)和朝向零(trunc)。

完成后,不要忘记将舍入模式设置回来。

显然frndint在某些 CPU 上速度很慢(https://agner.org/optimize),因此实际上可以更快地转换为整数并使用fistp/返回fild(仍然适当设置舍入模式)。但这仅适用于可以表示为有符号 64 位整数的 FP 值(假设您使用 qword 内存操作数)。您可以添加/减去适当的幻数(以使值非常大,强制舍入)。同样,这可能需要设置舍入模式。

当然,如果您愿意 (int)floor(x),那么绝对可以fistp根据需要设置舍入模式。

使用 SSE3,您可以使用fisttp截断为零(添加它是为了加速代码中的 C float->int 转换,即使 SSE 可用,代码中仍希望使用旧版 x87)。

floor == trunc对于非负值,因此您可以在这种情况下利用高效fisttp或 SSE XMM 截断。


对于 SSE4.1,对于doubleXMM 寄存器中的标量,您可以使用由立即数操作数指定的舍入模式来roundsd舍入到最接近的整数值。double(不是转换,只是像 一样双->双舍入frndint,所以它适用于任何值)。提供压缩和标量单精度和双精度版本。

对于 SSE4.1,roundsd+cvtsd2si是您的最佳选择(int)floor(x)。或者,如果您知道您的值是非负的,您可以使用 SSE2cvttsd2sit请注意“截断”的额外内容。(对于单精度或带有 . 的压缩 SIMD 来说也是如此cvtpd2dq。)