强制MSVC使用/ QIfist选项生成FIST指令

时间:2013-07-20 13:23:47

标签: visual-c++ x86 intel fpu

我经常使用/QIfist compiler switch,这会导致编译器生成FISTP指令以将浮点值舍入为整数,而不是调用_ftol辅助函数。

如何使用FIST(P) DWORD代替QWORD

FIST QWORD要求CPU将结果存储在堆栈中,然后将堆栈读入寄存器并最终存储到目标存储器,而FIST DWORD只是直接存储到目标存储器中。

1 个答案:

答案 0 :(得分:0)

  

FIST QWORD要求CPU将结果存储在堆栈中,然后将堆栈读入寄存器并最终存储到目标存储器,而FI​​ST DWORD只是直接存储到目标存储器中。

我不明白你在这里想说什么 FISTFISTP指令在两个方面有所不同:

  1. FISTP 弹出浮点数堆栈的最高值,而FIST则没有。这是明显的区别,并反映在操作码命名中:FISTP具有P后缀,这意味着“pop”,就像ADDP等等。

  2. FISTP 有一个额外的编码适用于64位(QWORD)个操作数。这意味着您可以使用FISTP将浮点值转换为64位整数。另一方面,FIST最大值为32位(DWORD)个操作数。

    (我认为没有技术上的原因。我当然无法想象它与弹出行为有关。我假设当英特尔工程师在一段时间后添加对64位操作数的支持时,他们认为没有理由不使用非弹出版本。他们可能已用完了操作码编码。)

  3. x86指令集有很多在线参考资料。例如,this site是大多数Google搜索的热门搜索。或者您可以查看Intel's manualsFIST / FISTP位于第365页)。

    两条指令读取的值,以及它们存储的值是完全相同的。两者都从浮点堆栈顶部读取值,并将结果存储到内存中。

    使用FIST代替FISTP的编译器绝对没有优势。请记住,当从函数退出时,始终必须从浮点堆栈中弹出所有值,因此如果使用FIST,则必须再追加FSTP FISTP 1}}指令。这可能不会慢,但它会不必要地膨胀代码。

    此外,还有另一个原因,编译器更喜欢FIST:支持64位操作数。它允许代码生成器完全相同,无论您要舍入到什么大小的整数。

    时间您可能更喜欢使用FIST,如果您是手写汇编代码并希望在堆栈之后重复使用浮点值四舍五入。编译器不需要这样做。

    所以,无论如何,所有这些都说明你的问题的答案是否定的。无法使编译器自动生成int32 RoundToNearestEven(float value) { int32 result; __asm { fld DWORD PTR value fist DWORD PTR result // do something with the value on the floating point stack... // // ... but be sure to pop it off before returning fstp st(0) } return result; } 指令。如果你仍然坚持,你可以编写使用你想要的任何指令的内联汇编:

    {{1}}