You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让GCC在整数寄存器中返回浮点类型值?

x86-64架构下禁用浮点寄存器返回浮点值的问题

x86-32架构的现有方案

针对x86(-32)架构,GCC提供了完全禁用x87 FPU指令生成的方式,转而调用软件实现浮点运算的库函数。这一功能最初是为适配早期无硬件FPU的x86 CPU(如i386、i486SX)设计,也适用于无法使用FPU的场景(如内核代码,不过通常内核代码并不使用浮点运算)。

  • 使用-mgeneral-regs-only可直接启用该功能,它会禁用x87、SSE、AVX等指令集的使用,但需要包含相关例程的libgcc版本。
  • 技术上也可通过-msoft-float -mno-fp-ret-in-387仅禁用x87,但这会允许编译器使用SSE优化,实用性不高。

x86-64架构的需求与遇到的问题

我希望在x86-64架构上实现同样的功能:完全禁用硬件浮点指令,仅用软件库函数处理浮点运算。

x86-64默认支持SSE2,GCC默认用其处理浮点运算,-msoft-float单独使用无作用(需同时设置-mfpmath=387才会生成库调用)。-mgeneral-regs-only可绕过x86-64 ABI中浮点参数通过XMM寄存器传递的规定,让编译器将所有浮点参数放在栈上,并生成浮点例程的库调用。

但核心问题是:x86-64 ABI要求浮点值通过XMM寄存器返回,目前找不到可禁用这一行为的开关(不同于x86-32架构,可通过-mno-fp-ret-in-387禁用在ST0中返回浮点值,尽管这也违反ABI)。我想知道是否存在让编译器在整数寄存器中返回浮点值的方法。

测试显示:接收double并返回int的函数(以及对__fixdfsi的库调用)可以正常工作,但返回double的函数仅在x86-32架构下可行,x86-64下编译器会严格遵循ABI要求用XMM寄存器返回。

补充问题

问题比预想更复杂:编译器会严格遵守System V ABI中关于long double的返回规定——即使该类型本应在ST0而非XMM0中返回,x86-64下也无法强制用整数寄存器返回。完全相同的编译标志在32位模式下有效(在ecx:edx:eax中返回),但64位模式下无效,尤其是-mno-fp-ret-in-387完全不起作用。


内容的提问来源于stack exchange,提问作者DarkAtom

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 11:05:09