首页 > 解决方案 > 为什么 PowerPC 的 stfs 指令没有按预期运行?

问题描述

PowerPC 的浮点寄存器只支持双精度格式,因此加载和存储单精度值需要转换。在加载时从单到双的转换是有道理的,但是从双到单的转换用于存储会造成一些令人困惑的事情。它似乎正确地截断了单精度范围内的数字,以及 NaN、无穷大和零,但对其他所有内容做了一些奇怪的移位,而不是像我期望的那样四舍五入到零或无穷大。

来自 PPC750 CPU 的示例。首先列出了给出我预期结果的示例。

double-precision input    decimal approximation    single-precision output    decimal approximation

0x 400f ffff ffff ffff    3.99999999               0x 407f ffff               3.99999976
0x 7ff8 0000 0000 0000    QNaN                     0x 7fc0 0000               QNaN
0x 7ff0 0000 0000 0000    +inf                     0x 7f80 0000               +inf
0x 8000 0000 0000 0000    -0.0                     0x 8000 0000               -0.0
--------------------------------------------------------------------------------------------------
0x 8000 0000 0000 0001    -4.941e-324              0x 8080 0000               -1.175e-38
0x 00a0 0000 0000 0000    1.139e-305               0x 0500 0000               6.019e-36
0x 7fe0 1234 5678 9abc    9.028e+307               0x 7f00 91a2               1.709e+38

我查看了PowerPC Programming Environments Manual 以了解它是否可以对此有所了解。第 C.7 节描述了“不需要非规范化”和“需要非规范化”情况的转换步骤。(请注意,||在此符号中表示串联。)

转换步骤

然后它继续说:

请注意,如果要由单精度存储浮点指令存储的值的大小大于单一格式可表示的最大数,则适用第一种情况,“不需要反规范化”。存储在 WORD 中的结果是一个定义明确的值,但在数值上不等于源寄存器中的值(也就是说,从 WORD 中加载单精度浮点的结果不等于原始源寄存器)。

这解释了为什么我得到了我所做的结果,但它并没有解释它有什么用处。在我看来,如果再次从内存中加载这些值会导致可怕的错误。

为什么 stfs 指令不执行正常舍入?预期结果如何不会引起问题?

标签: floating-pointpowerpc

解决方案


文档说“请注意,在执行stfs指令stfs之前,要存储的值应该是单精度格式。” 这意味着要存储的寄存器的内容应该是一些产生单精度值的先前指令的结果,例如(单精度浮点乘法)或(舍入到单精度)。fmulsfrsp

我会冒险猜测部分原因是它可以快速且易于实现 - <code>stfs 不必进行舍入,也不必使用浮点单元来执行此操作。它可以直接进入加载存储单元,该单元仅具有处理更简单情况的逻辑,其中截断位就足够了。


推荐阅读