MinGW gcc设置fp舍入模式

MinGW gcc设置fp舍入模式,c,gcc,assembly,floating-point,mingw,C,Gcc,Assembly,Floating Point,Mingw,我正在使用gcc编译器,我希望能够快速更改sse舍入模式。如果在linux下编译,以下代码可以工作: #include <xmmintrin.h> unsigned int _mxcsr_up = _MM_MASK_MASK | _MM_ROUND_UP; unsigned int _mxcsr_down = _MM_MASK_MASK | _MM_ROUND_DOWN; unsigned int _mxcsr_n = _MM_MASK_MASK; void round_neare

我正在使用gcc编译器,我希望能够快速更改sse舍入模式。如果在linux下编译,以下代码可以工作:

#include <xmmintrin.h>
unsigned int _mxcsr_up = _MM_MASK_MASK | _MM_ROUND_UP;
unsigned int _mxcsr_down = _MM_MASK_MASK | _MM_ROUND_DOWN;
unsigned int _mxcsr_n = _MM_MASK_MASK;

void round_nearest_mode() {
    asm (
    "ldmxcsr %0" : : "m" (_mxcsr_n)
    );
}

void round_up_mode() {
    asm (
    "ldmxcsr %0" : : "m" (_mxcsr_up)
    );
}

void round_down_mode() {
        asm (
        "ldmxcsr %0" : : "m" (_mxcsr_down)
        );
}
#包括
无符号整数_mxcsr_up=_MM_MASK_MASK | _MM_ROUND_up;
无符号整数_mxcsr_down=_MM_MASK_MASK | _MM_ROUND_down;
无符号整数_mxcsr_n=_MM_掩码_掩码;
无效圆形\u最近的\u模式(){
asm(
“ldmxcsr%0”:“m”(\u mxcsr\u n)
);
}
无效取整模式(){
asm(
“ldmxcsr%0”:“m”(\u mxcsr\u up)
);
}
无效四舍五入向下模式(){
asm(
“ldmxcsr%0”:“m”(\u mxcsr\u向下)
);
}

但当我在windows下使用MinGW编译它时,舍入模式没有改变。原因是什么?

提供
\u MM\u ROUND\u UP
常量的标题也定义了相关指令的内部包装

通常,您应该检索旧值或ANDN要更改的位,然后应用新值。(例如,
mxcsr&=~一些位
)。您不会发现很多只使用LDMXCSR而不先执行STMXCSR的示例

哦,我认为你的代码中的那部分实际上是错的。我没有研究过
\u MM\u MASK\u MASK
是如何定义的,但它的名称包括单词MASK。你要用其他常数对它进行O型运算,而不是对它进行AND运算您可能每次都将MXCSR设置为相同的值,因为您正在使用
\u MM\u MASK\u MASK
对所有内容进行ORing,我假设已设置了所有舍入模式位。


正如@StoryTeller指出的,您不需要内联asm或内部函数来更改舍入模式,因为x86硬件提供的四种舍入模式与C99:()中由
fenv.h
定义的四种模式相匹配,您可以使用它们进行设置

如果要动态更改舍入模式,并确保优化器不会将任何FP ops重新排序到舍入模式设置不同的位置,则需要
#pragma STDC FENV_访问
。另见


使用
asm volatile
手动执行此操作仍然不会阻止CSE认为先前计算的
x/y
是相同的值,并且不会在asm语句后重新计算它。除非您使用
x
y
作为从未实际使用过的asm语句的读写操作数。e、 g

asm volatile("" : "+g"(x));  // optimizer must not make any assumptions about x's value.

您可以将LDMXCSR放在同一个内联asm语句中,以确保舍入模式更改的点也是编译器将
x
视为已更改的点。

如果您在托管环境中,t@StoryTeller我包括但我不能使用它的内容。我认为“if#GLIBCXX_USE_C99_FENV_TR1”的条件不满足,但我不知道为什么。将您的项目构建为C99。将
-std=c99
添加到编译器调用中(或者如果使用IDE,则在项目选项中查找该选项)。是什么让您认为模式没有更改?你是如何测试这个的?@DavidWohlferd:我认为他真的没有改变取整模式,因为他是在对_MM_MASK_MASK_MASK_MASK进行排序,而不是对其进行AND运算。