这里需要保存FPU状态吗?
Is it necessary to save the FPU state here?
我写了一个简单的协作多线程库。目前我总是在切换到新上下文时使用 fxsave
/ fxrstor
保存和恢复 fpu 状态。但这在 cdecl 调用约定中是必要的吗?
举个简单的例子:
float thread_using_fpu(float x)
{
float y = x / 2; // do some fpu operation
yield(); // context switch, possibly altering fpu state.
y = y / 2; // another fpu operation
return y;
}
编译器是否可以在调用 yield()
后对 FPU 状态做出任何假设?
没有。您不必对状态进行任何保存。如果一个线程正在进行浮点计算,例如设置了非规范化标志,并且该线程被中断,那么当它恢复时 O/S 或内核将设置标志,就像它一样将恢复其他寄存器。同样,您不必在 yield() 中担心它。
编辑:如果您要进行自己的上下文切换,并且需要将它们设置为非默认值,则可能需要保存精度和舍入控制标志。否则,你又没事了。
根据 SYSTEM V APPLICATION BINARY INTERFACE Intel386TM Architecture Processor Supplement,第 3-12 页:
%st(0): If the function does not return a floating-point value, then this
register must be empty. This register must be empty before
entry to a function.
%st(1) through %st(7):
Floating-point scratch registers have no specified role in the
standard calling sequence. These registers must be empty before entry
and upon exit from a function.
因此,您不需要对它们进行上下文切换。
另一个,newer version 是这样说的:
The CPU shall be in x87 mode upon entry to a function. Therefore, every function that uses the MMX registers is required to issue an
emms or femms instruction after using MMX registers, before returning
or calling another function. [...]
The control bits of the MXCSR register are callee-saved (preserved across calls), while the status bits are caller-saved (not preserved).
The x87 status word register is caller-saved, whereas the x87 control
word is callee-saved.
[...] All x87 registers are caller-saved, so callees that make use of the MMX registers may use the faster femms instruction.
所以,您可能需要保存控制字。
我写了一个简单的协作多线程库。目前我总是在切换到新上下文时使用 fxsave
/ fxrstor
保存和恢复 fpu 状态。但这在 cdecl 调用约定中是必要的吗?
举个简单的例子:
float thread_using_fpu(float x)
{
float y = x / 2; // do some fpu operation
yield(); // context switch, possibly altering fpu state.
y = y / 2; // another fpu operation
return y;
}
编译器是否可以在调用 yield()
后对 FPU 状态做出任何假设?
没有。您不必对状态进行任何保存。如果一个线程正在进行浮点计算,例如设置了非规范化标志,并且该线程被中断,那么当它恢复时 O/S 或内核将设置标志,就像它一样将恢复其他寄存器。同样,您不必在 yield() 中担心它。
编辑:如果您要进行自己的上下文切换,并且需要将它们设置为非默认值,则可能需要保存精度和舍入控制标志。否则,你又没事了。
根据 SYSTEM V APPLICATION BINARY INTERFACE Intel386TM Architecture Processor Supplement,第 3-12 页:
%st(0): If the function does not return a floating-point value, then this register must be empty. This register must be empty before entry to a function.
%st(1) through %st(7): Floating-point scratch registers have no specified role in the standard calling sequence. These registers must be empty before entry and upon exit from a function.
因此,您不需要对它们进行上下文切换。
另一个,newer version 是这样说的:
The CPU shall be in x87 mode upon entry to a function. Therefore, every function that uses the MMX registers is required to issue an emms or femms instruction after using MMX registers, before returning or calling another function. [...] The control bits of the MXCSR register are callee-saved (preserved across calls), while the status bits are caller-saved (not preserved). The x87 status word register is caller-saved, whereas the x87 control word is callee-saved. [...] All x87 registers are caller-saved, so callees that make use of the MMX registers may use the faster femms instruction.
所以,您可能需要保存控制字。