X86 查询关于遗留3DNow!指令集

X86 查询关于遗留3DNow!指令集,x86,legacy,instruction-set,amd-processor,mmx,X86,Legacy,Instruction Set,Amd Processor,Mmx,只是为了好玩,我在回顾AMD推出的遗留(弃用)指令,并试图了解它们是如何使用的。所有指令似乎都按照以下模式编码: instruction destination_MMn_register_operand, source_MMn_register_or_memory_operand 其中destinationRegister=destinationRegister-操作-源代码 例如,类似于,pfadd mm0,mmword ptr[rcx](0F 0F 01 9E): 将从rcx指向的内存中

只是为了好玩,我在回顾AMD推出的遗留(弃用)指令,并试图了解它们是如何使用的。所有指令似乎都按照以下模式编码:

instruction destination_MMn_register_operand, source_MMn_register_or_memory_operand
其中
destinationRegister
=
destinationRegister
-操作-
源代码

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

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

因此,这些3DNow指令似乎总是有一个
mm
寄存器作为目标

但是你应该如何从那些
mm
寄存器中得到结果呢


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

实际上有,即
movd
movq
。这些说明不属于3DNow!,他们已经出现在MMX中,现在!是对的扩展。这也是为什么现在!包含一组看起来非常不完整的整数运算。

实际上有,即
movd
movq
。这些说明不属于3DNow!,他们已经出现在MMX中,现在!是对的扩展。这也是为什么现在!包括一组看起来非常不完整的整数运算。

正如@harold所说,MMX
movd
已经涵盖了存储到内存,或者
pshufw
+
movd
只提取高
浮点值

你不能做的一件事就是现在就开始做!浮点转换为x87 80位浮点,无需存储/重新加载

可能有用的是一个版本的EMMS,它在
st0
中将32位
浮点扩展为80位x87
长双精度
,同时将FPU设置回x87模式而不是MMX模式1。或者甚至可以将多个
mm
寄存器转换为多个x87寄存器

i、 e.
movd-dword[esp]、mm0
/
emms
/
fld-dword[esp]
设置SIMD缩减后的进一步标量FP是一种快捷方式

记住这些是IEEE754
float
s;通常情况下,您不希望它们出现在整数寄存器中,除非您正在分离它们的位字段(例如,对于
exp
log
实现),但您可以使用MMX移位/掩码指令来实现


但是movd和fld很便宜,所以他们不需要费心制作特殊指令来节省重新加载延迟。而且,它作为一条指令实现起来可能很慢。尽管x86不是RISC ISA,但拥有一条真正复杂的指令通常比多条简单的指令慢(尤其是在解码到多个UOP之前)例如,英特尔和AMD的
sysenter
syscall
指令用于替换系统调用的
int 0x80
,在保存更多状态之前/之后需要额外的指令,但总体而言速度更快

现在s,仅将标记字设置为未使用,而不是保留从MMX寄存器到x87寄存器内容的映射。有关AMD的官方手册,请参阅。IDK如果AMD的微体系结构刚刚删除了寄存器重命名信息或其他什么,但可能使store/femms/x87以快速方式加载可以节省大量晶体管

甚至FEMMS仍然有点慢,所以他们不想鼓励编码人员离开/重新进入MMX/3dNow!我经常是这样


有趣的事实:现在开始<代码>预回迁w
(带写意图的预回迁)仍在使用,并且有自己的CPUID功能位。

请看我的答案

Intel CPU很快增加了对解码为NOP的支持(因此64位Windows等软件可以不检查就使用它),但Broadwell和后来的处理器实际上使用RFO进行预取,以使缓存线处于MESI独占状态,而不是共享状态,因此它可以切换到修改状态,而无需额外的非核心流量

CPUID功能位表示它确实将预取


脚注1

请记住,MMX寄存器别名为x87寄存器,因此不需要新的操作系统支持来保存/恢复上下文交换机上的体系结构状态。直到我们有了新的建筑状态。所以直到SSE2+3dNow!那真是个好主意<代码>浮动
到SSE2
double
在不切换回x87模式的情况下是有意义的。而你可以+


他们可以在
mm
寄存器中有一个float->double,但是
fld
/
fst
硬件仅为
float
double
->80位和80位->
float
double
设计。并且其用例是有限的;如果您使用的是3dNow!,只要坚持
float

就可以了,正如@harold所说,MMX
movd
pshufw
+
movd
已经涵盖了存储到内存的功能,只提取高
float

你不能做的一件事就是现在就开始做!浮点转换为x87 80位浮点,无需存储/重新加载

可能有用的是一个版本的EMMS,它在
st0
中将32位
浮点扩展为80位x87
长双精度
,同时将FPU设置回x87模式而不是MMX模式1。或者甚至可以将多个
mm
寄存器转换为多个x87寄存器

i、 e.
movd-dword[esp]、mm0
/
emms
/
fld-dword[esp]
设置SIMD缩减后的进一步标量FP是一种快捷方式

记住这些是IEEE754
float
s;通常情况下,您不希望它们出现在整数寄存器中,除非您正在分离它们的位字段(例如,对于
exp
log
实现),但您可以使用MMX移位/掩码指令