在st0中存储通用寄存器

问题描述 投票:2回答:2

如果我在rax中有某个值(位模式,假设全为零),我可以将其存储在st0中而无需存储和从内存中加载吗?

x86 floating-point x86-64 x87
2个回答
1
投票

您可以使用许多指令将常量加载到FPU寄存器堆栈。我认为这里最有用的是FLD1FLDZ,它们分别将+1.0和+0.0加载到堆栈上。如果RAX可能保留的唯一整数是1和0,则可以有条件地执行FLD1FLDZ

通常,无符号或二进制补码格式的任何64位整数都可以用80位扩展精度浮点格式表示。可以使用零存储器访问将RAX中找到的所有整数值加载到FPU堆栈上。这可以通过使用一系列x87算术指令来实现,这些指令可能在一个循环中执行,其行程数保存在GP寄存器中。一种方法是使用FADD(对于负整数为FSUB),直到st0包含所需的整数值,尽管对于大(绝对)值来说这可能非常慢。对2的幂的整数有效的一种可能的优化方法是加载常数+1.0,使用FADD将其加1以得到数字2,然后使用FMUL直到达到所需的2的幂。在某些情况下可能更快的另一种方法是首先分解RAX中的整数,使用FADD构造每个素数,然后使用FMUL乘以素数。

所有这些说明在所有Intel和AMD x86处理器上均受支持。


1
投票

我认为您实际上想要Long latency instruction其中movd /movq+ sqrtsssqrtsd比??更容易工作-> fsqrt。

fcmovcc通过整数标志将整数依赖关系耦合到x87依赖关系>>而不是通过传输位模式来完成。在Skylake上,这是4位指令,但在4位ALU位。

在另一个方向上,fcmovcc + fcomi

setcc或什至只是cmovcc + fcom

正如@Hadi指出的那样,您可以使用fnstsw ax(1 uop)或fldz(2 uops)在x87寄存器中创建值。然后根据需要使用fld1或类似名称将其设置为依赖。


[[可能的答案,因为它不太可能有用,所以还没有得到充分的研究] >>对您来说(可能涉及微码fcmovne st0, st1:Skylake上为10 uops,Haswell上为31 uops。)

也许您可以使用emms,然后使用movq mm0, rax离开MMX状态

。这会将所有x87寄存器标记都标记为“空”。[根据emms,在当前的AMD上,FEMMS与EMMS相同,但我似乎还记得,以前的AMD CPU上的FEMMS并未定义x87寄存器。也许这对某些东西有用。它仍然设置标签词,因此未定义的内容可能仅与可能希望在EMMS之后找到AMD's 2018-may PDF ISA reference manual内容并再运行另一MMX指令的情况相关。或以mm0..7状态查找数据。

64位MMX寄存器别名80位x87寄存器的有效数(尾数)。

(我认为)。 fxsave堆栈映射到从x87状态字中的3位TOP字段索引的寄存器开始的那些基础80位寄存器。 (st0..7用左轮手枪的枪管很好地描述了这一点。我不确定这是否真的可用,但是我不认为http://www.ray.masmcode.com/tutorial/fpuchap1.htm清除emms / st寄存器的内容,仅清除x87标签。 ([mm说“将x87 FPU标记字中的所有标记的值设置为空(全1)”

如果在EMMS指令重置x87 FPU标记字之前,浮点指令将x87 FPU数据寄存器堆栈中的一个寄存器加载,则会发生x87浮点寄存器堆栈溢出,从而导致x87浮点异常或错误结果。

它只说“可以”,而不是“将”。也许在x87元数据处于已知状态的情况下,您可以将MMX指令和x87指令与某种一致的行为混合在一起吗?至少在特定的微体系结构上。

您无法读取标记字为Intel's vol.2 entry for emms(表示空)的x87寄存器,并且没有emms,只有11可以将单个标记字设置为funfree(不会影响页首-stack指针或内容)。

您必须ffree并修改已保存的x87状态元数据(包括32/64位模式下的填充在内的28个字节的标记字,然后再单击ffree

或者您可以为11准备好一个预定义的x87“环境”,并将某些标记词设置为不使用。 (但是Agner Fog甚至没有安排该指令的时间。它显然将被微编码,并且可能很慢。)您可能可以在没有fstenv的情况下使用它,但是它仍然是一个微编码的指令。

相关:fldenv有一些我不久前挖出的关于fldenv的链接,还有多少3dNow!可以与上交所互动。嗯,显然,它仍然会将标记字设置为所有未使用的字,但是并没有保留fldenv和x87寄存器之间的已知映射。

© www.soinside.com 2019 - 2024. All rights reserved.