fstcw assembly operand type mismatch

浪子不回头ぞ 提交于 2019-12-11 20:07:29

问题


I'm trying to round an input double using a specified rounding mode in in-line assembly in C. To do so, I need to grab the FPU control word using "fstcw" and then change the bits in the word. Unfortunately I'm encountering an error on the very first line:

double roundD(double n, RoundingMode roundingMode) {
    asm("fstcw      %%ax       \n"

        ::: "ax");      //clobbers

    return n;
}

The assembler error I receive is:

"Error: operand type mismatch for 'fstcw'."

I'm under the impression this code snippet should store the FPU control word, which is 16 bits in length, in the AX register, which is also 16 bits in length. Just to be sure, I also tested the above code with the EAX register instead of AX, and received the same error.

What might I be missing here? Please let me know if any further information is needed.


回答1:


fstcw only works with a memory destination operand, not register.

Perhaps you're getting mixed up with fnstsw which has a separate form (separate opcode) where the destination is AX instead of specified by an addressing mode.

That was needed to efficiently branch based an an FP compare result (before fcomi to compare into EFLAGS existed), which happens more often than anything with the control word. That's why there's an AX-destination version of fnstsw but not fnstcw.


And BTW, you can set the rounding mode using C. #include <fenv.h>

Or far better, if SSE4.1 is available, use roundsd (or the intrinsic) to do one rounding with a custom rounding mode, without setting / restoring the SSE rounding mode (in MXCSR, totally separate from the x87 rounding mode).



来源:https://stackoverflow.com/questions/48981197/fstcw-assembly-operand-type-mismatch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!