所有 x86-64 实现都支持 CMOVcc 指令吗?

ecm*_*ecm 3 assembly x86-64 instruction-set

在我对问题汇编代码返回数组中最小整数而不是随机返回最后一个或倒数第二个数字的问题中,我提出了使用指令的替代方案cmovcc。我在那里指出:

cmov指令似乎所有 AMD64 CPU 都支持。

然而,当时我还没有找到确凿的消息来源来支持这一说法。所以我想发布这个问题来询问这个问题。

Pet*_*des 5

是的,实际上所有 x86-64 CPU 都支持cmovcc,并且人们普遍认为无需检查其 CPUID 功能位即可安全使用。即长模式支持的特征位暗示了这一点。

\n\n
\n\n

cmovcc是在x86-64 之前的Intel P6 (PPro 等)中引入的,并支持所有后来的 Intel CPU(除了 Quark 和 KNC,它们是基于P5 的非通用设计,但它们都不是 x86-64 1 AMD cmovcc的首款 AMD64 CPU (K8) 以及之前的 K7 也支持,但 K6 不支持。Via 的 x86-64 CPU 也支持 CMOV。据我所知,没有其他 x86-64 硬件供应商,并且软件模拟器都支持 CMOV 作为 x86-64 的一部分。

\n\n

许多其他供应商出售支持 CMOV 的 32 位 CPU,包括 Cyrix 6x86MX/MII,可能是 Transmeta Crusoe 二进制翻译层的一些更新,以及Via C3 Nehemiah

\n\n

各种 CPU 上 32 位 CMOV 支持的来源:Agner Fog 的“停止指令集之战”博客文章的 评论、 reactOS 兼容列表以及Fedora bug的讨论。

\n\n

脚注 1:Quark 和 KNC 此后均已停产。 Quark是一个普通的 32 位微控制器。 KNF / KNC为第一代 Xeon Phi 提供动力,并且是它自己的东西:不完全兼容 x86-64,例如没有 CMOV 或 SSE,仅支持其前身 AVX512。我认为它有某种方法可以处理超过 4GiB 的 RAM。下一代 Xeon Phi KNL /KNM 是真正的 x86-64(源自 Silvermont),具有 cmov 和普通 AVX + AVX512F。并且已经停产了。)

\n\n
\n\n

cmovx86-64 的编译器都假设在生成 64 位代码时可以安全使用。

\n\n

这很重要,因为像 gcc 这样的编译器不会假设 x86-64 的一些早期添加,除非您使用特殊选项。例如lock cmpxchg16b(早期 AMD 中缺少)或lahf长模式(早期支持 64 位的 Intel P4 中缺少)。GCC确实采用cmov默认值这一事实-march=x86-64表明假定了普遍支持。

\n\n

(GCC 通常配置为 32 位模式 codegen,假设 Pentium Pro,也使用cmov但不使用 SSE1。例如,在 Godbolt 上使用 4.6 版本的return a ? b:c;gcc 编译为 cmov 。这绝对不是32 位模式的基线,并且在 P5 Pentium 及更早版本上会出现故障。GCC 通常配置为在 32 位模式下以“i686”为目标,但对于 64 位模式来说,真正的基准 x86-64 因为它仍然功能齐全,不会太糟糕。)-m32

\n\n
\n\n

不过,我不知道你在哪里可以找到关于它是基线的官方确认;英特尔手册(https://www.felixcloutier.com/x86/cmovcc)确实这样说:

\n\n
\n

P6 系列处理器中引入了CMOVcc 指令;但是,并非所有 IA-32 处理器都支持这些指令。软件可以通过CPUID指令检查处理器\xe2\x80\x99s功能信息来确定是否支持CMOVcc指令(请参阅本章中的\xe2\x80\x9cCPUID\xe2\x80\x94CPU标识\xe2\x80\x9d) 。

\n
\n\n

(相关的 CPUID 功能位是cpuid[EAX=1].EDX.bit15沙堆或 EAX=8000_0000h),这也表示支持其他 P6 功能,例如fcomi如果fcmovcc存在 x87 FPU,即0设置了相同 EDX 输出的位。)

\n\n

认为IA-32 措辞意味着没有 IA-32e 处理器(Intel 对 x86-64 的命名)缺少它,只有一些 IA-32 处理器缺少它。但这不是一个非常明确的陈述,基于我知道它在实践中是正确的事实,我可能会过度解释。

\n\n
\n\n

这个问题的另一个答案指出了SSE2。实际上,所有支持 SSE2 的 CPU 也支持cmov,但cmov不是“SSE2 的一部分”。它们具有单独的 CPUID 功能位。(两者都是 x86-64 的基线,因此 64 位代码不需要检查功能位。)

\n\n

没有什么可以阻止某人使用 SSE2 构建 CPU,但cmov事实并非如此……除了没有人会购买它,因为它无法运行正常的二进制文件。许多现代编译器即使在 32 位模式下也使用 CMOV,即使它们默认不使用 SSE1。(这可能看起来有点愚蠢;仍在使用的 PPro / PII CPU 数量可能并不比 P5 Pentium 和兼容 CPU 高多少。但是半现代的 AMD Geode 具有没有 SSE1 的 CMOV。https: //bugzilla.redhat.com /show_bug.cgi?id=538268#c9 )

\n

  • @HadiBrais:https://reactos.org/wiki/Supported_Hardware/CPU 提到 Cyrix 6x86MX/MII 对 CMOV 和 MMX 的支持。我知道根据 https://bugzilla.redhat.com/show_bug.cgi?id=538268#c9 中的讨论来搜索 cyrix cmov。哦,我还发现 https://www.agner.org/optimize/blog/read.php?i=82&v=t 据“停止指令集战争”中的评论者称,Transmeta Crusoe 在某些时候支持 CMOV “ 线。 (2认同)