C 禁用SSE的SSE寄存器返回

C 禁用SSE的SSE寄存器返回,c,gcc,floating-point,sse,C,Gcc,Floating Point,Sse,我的情况如下: 我正在为不允许SSE指令的内核编写代码 我需要做浮点运算 我正在为x86_64平台编译 下面是一个说明问题的代码示例: int main(int argc, char** argv) { double d = 0.0, dbase; uint64_t base_value = 300; d = (2200.0 - 1000.0)/(1000.0); dbase = d * base_value; printf("d = %f, dba

我的情况如下:

  • 我正在为不允许SSE指令的内核编写代码
  • 我需要做浮点运算
  • 我正在为x86_64平台编译
下面是一个说明问题的代码示例:

int
main(int argc, char** argv)
{
    double d = 0.0, dbase;
    uint64_t base_value = 300;

    d = (2200.0 - 1000.0)/(1000.0);
    dbase = d * base_value;
    printf("d = %f, dbase = %f\n", d, dbase);
    base_value = dbase;
    printf("base_value = %llu\n", (long long unsigned)base_value);
    return 0;
}
下面是makefile中的相关行:

CFLAGS +=   -mcmodel=kernel -mno-red-zone -mfpmath=387 -mno-sse -mno-sse2 -mno-mmx -mno-3dnow \
            -msoft-float -fno-asynchronous-unwind-tables -fno-omit-frame-pointer
当我运行生成时,会出现以下错误:

SSE register return with SSE disabled
(错误指向将d与base_值相乘的直线)

你知道我能做些什么来解决这个问题吗?删除-mno-sse不是一个选项,但编译器似乎应该能够生成非sse代码来执行乘法

谢谢
Nathan

听起来好像编译器正在向库例程发出一个调用,以便为您执行浮点乘法(可能不使用SSE),但正在尝试为调用使用ABI,该调用的返回值在SSE中传递。显然,这是行不通的

如果可以在内核中使用浮点,那么应该有一个特殊的运行库来执行软浮点操作,它不使用通常的(userland)参数传递和返回约定。然而,据我所知,BSD内核中不支持浮点。几年前确实如此


您可能只需要询问BSD内核开发人员电子邮件列表是否可以使用浮点;我怀疑它会给你一个更快、更明确的答案。

听起来好像编译器正在向库例程发出一个调用,以便为你执行浮点乘法(可能不使用SSE),但正在尝试对调用使用ABI,该调用的返回值在SSE中传递。显然,这是行不通的

如果可以在内核中使用浮点,那么应该有一个特殊的运行库来执行软浮点操作,它不使用通常的(userland)参数传递和返回约定。然而,据我所知,BSD内核中不支持浮点。几年前确实如此


您可能只需要询问BSD内核开发人员电子邮件列表是否可以使用浮点;我怀疑它会给你一个更快更明确的答案。

gcc可能无法处理这种情况,因为它假设所有x86-64处理器都有SSE。这是否意味着没有人在64位版本上复制FreeBSD内核中的任何内容?我所使用的任何内核都倾向于尽可能避免浮点。是的。内核人员讨厌需要保存和恢复更多寄存器。gcc可以很好地进行x87运算(如果您告诉内核保存/恢复用户空间x87 FPU状态)。问题是将
double
作为函数arg传递,因为您正在编译一个调用约定,该约定在XMM寄存器中传递
double
args。如果您省略了printf(“d=%f,dbase=%f\n”,d,dbase),,您可以编写使用FP math的函数,即使使用
-mno sse
:例如,请参阅从一个简单函数获得的asm输出。gcc可能无法处理这种情况,因为它假设所有x86-64处理器都有sse。这是否意味着没有人在64位构建上倍增FreeBSD内核中的任何内容?我所使用的任何内核都倾向于尽量避免浮点数。内核人员讨厌需要保存和恢复更多寄存器。gcc可以很好地进行x87运算(如果您告诉内核保存/恢复用户空间x87 FPU状态)。问题是将
double
作为函数arg传递,因为您正在编译一个调用约定,该约定在XMM寄存器中传递
double
args。如果您省略了printf(“d=%f,dbase=%f\n”,d,dbase),您可以编写使用FP-math的函数,即使使用
-mno-sse
:例如,有关简单函数的asm输出,请参阅。我决定改用定点算术(所讨论的内核是基于FreeBSD内核的,但经过了重大修改,因此我不确定任何官方邮件列表是否会给出比“不要那样做”更好的答案。啊。很抱歉,对于这个问题没有更好的答案。我决定改为使用定点算法(所讨论的内核是基于FreeBSD内核的,但经过了重大修改,因此我不确定任何官方邮件列表是否会给出比“不要那样做”更好的答案。啊。很抱歉,没有比这个更令人满意的答案。