查询旧版3DNow!指令系统

时间:2018-08-06 20:47:33

标签: x86 amd legacy instruction-set mmx

仅出于娱乐目的,我正在回顾AMD引入的3DNow! set中的旧(不推荐使用)指令,并且试图了解它们的用法。所有指令似乎都按照这种模式编码:

instruction destination_MMn_register_operand, source_MMn_register_or_memory_operand

其中destinationRegister = destinationRegister-操作-source

例如,pfadd mm0, mmword ptr [rcx]0F 0F 01 9E):

enter image description here

rcx指向的内存中的2个压缩浮点数加到mm0中存储的2个压缩浮点数中,并将结果保留在mm0中。

因此,似乎这些3DNow指令始终具有mm寄存器作为目的地。

但是您应该如何从那些mm寄存器中获取结果?

换句话说,没有mov mmword ptr [rcx], mm0mov rax, mm0指令。

2 个答案:

答案 0 :(得分:3)

实际上有movdmovq。这些说明不是3DNow!的一部分,它们已经存在于3DNow!的MMX中。是的扩展。这也是3DNow的原因!包括一组看起来很不完整的整数运算。

答案 1 :(得分:3)

正如@harold所说,存储到内存已被MMX movdpshufw + movd所覆盖,仅提取高float

您不能做的一件事就是打开3dNow!浮动到x87 80位浮动中,而无需存储/重新加载。

可能有用的是一个EMMS版本,该版本将float中的32位long double扩展为80位x87 st0,并将FPU设置为x87模式而不是MMX模式 1 。甚至对多个mm寄存器到多个x87寄存器都可以这样做?

即在简化SIMD之后,movd dword [esp], mm0 / emms / fld dword [esp]可以设置进一步的标量FP。

请记住,它们是IEEE754 float;您通常不希望它们在整数寄存器中,除非您要分离它们的位字段(例如,用于explog实现),但是您可以使用MMX移位/掩码指令来实现。


但是movd和fld很便宜,因此他们不必费心做一个专门的指令来节省重载延迟。同样,将其作为单个指令实施可能会很慢。即使x86不是RISC ISA,拥有一个真正复杂的指令通常也比多个简单的指令慢(特别是在解码为多个微指令之前完全是一件事情)。英特尔和AMD的sysentersyscall指令(用于替换int 0x80来进行系统调用)在存储更多状态之前/之后需要附加的指令,但总体上还是更快。

3dNow!的femms leaves the MMX/3dNow! register contents undefined,仅将标记字设置为未使用,而不保留从MMX寄存器到x87寄存器内容的映射。有关AMD的官方手册,请参见http://refspecs.linuxbase.org/AMD-3Dnow.pdf。 IDK如果AMD的微体系结构只是放弃了寄存器重命名信息或其他内容,但可能以快速的方式存储/ femms / x87-load可以节省很多晶体管。

甚至FEMMS仍然有些慢,因此他们不想鼓励编码人员离开/重新进入MMX / 3dNow!模式。


有趣的事实:3dNow!仍然使用PREFETCHW(具有写意图的预取),并且具有自己的CPUID功能位。

What is the effect of second argument in _builtin_prefetch()?上查看我的答案

Intel CPU很快增加了对将其解码为NOP的支持(因此,诸如64位Windows之类的软件无需检查即可使用它),但是Broadwell和更高版本实际上是通过RFO预取的,以使高速缓存行处于MESI Exclusive状态,而不是已共享,因此无需额外的核心外流量就可以切换到“已修改”。

CPUID功能位指示它确实会预取。


脚注1

请记住,MMX寄存器是x87寄存器的别名,因此不需要新的OS支持就可以在上下文切换器上保存/恢复体系结构状态。直到SSE,我们才有了新的架构状态。所以直到SSE2 + 3dNow! 3dNow!从float到SSE2 double可能会有意义,而无需切换回x87模式。您可以movq2dq xmm0, mm0 + cvtps2pd xmm0, xmm0

他们可能在mm寄存器中有一个float-> double,但是fld / fst硬件仅设计用于floatdouble -> 80位和80位-> floatdouble。而且用例有限。如果您使用的是3dNow !,请坚持使用float