为什么__builtin_parity相反?

Why is __builtin_parity opposite?

GCC 和 Clang 都支持名为 __builtin_parity 的实现定义函数,它有助于确定数字的奇偶校验。

根据what GCC states

Built-in Function: int __builtin_parity (unsigned int x)
    Returns the parity of x, i.e. the number of 1-bits in x modulo 2.

这意味着如果1位的个数是偶数,它会return0和1如果是奇数。

我在 Compiler Explorer.

上测试的 Clang 也是如此

但是,实际的parity flag是设置的位数为偶数时设置的

为什么会这样?

它们只是不同的任意选择。

首先请注意,“实际奇偶校验标志”是仅在某些体系结构上提供的硬件功能;在目前主流使用的架构中,我认为 x86 是唯一带有这种标志的架构。因此,这种标志的存在,更不用说确切的语义,无论如何都不是通用标准。

我觉得GCC的选择比较符合逻辑:0和1应该分别对应偶数和奇数,因为0是偶数,1是奇数。我不知道为什么 x86 和它的前辈选择反其道而行之。您可能不得不回到过去并询问设计师。

不管怎样,8086校验标志的实际值不是很重要;程序员通常会使用 JPEJPO 汇编器助记符来测试它,这样您就可以指定“如果奇偶校验为偶数则跳转”或“如果奇偶校验为奇数则跳转”而不必记住哪个对应于 0 或 1咬在旗帜上。只有在您想通过 PUSHFLAHF 实际检查 FLAGS 寄存器中的位时,该值才会变得相关,这仅在非常模糊的情况下才有用。

我稍微看了看历史。 Intel 8086 从 8080 复制了它的标志,8080 也是如此。它的前身 8008 也有一个奇偶校验“触发器”,它似乎设置为偶校验,但有点不清楚,因为你只能根据触发器的状态有条件地跳转,而不是实际读取它。据说 8008 源自 Datapoint 2200,它实际上以相反的方式记录其奇偶校验翻转:设置为奇数,重置为偶数。但是 80xx 语义可能是一些没有任何深远意义的内部实现细节,例如奇偶校验电路恰好以这种方式产生结果,并且他们没有费心添加另一个 NOT 门来反转它。任何进一步的调查可能更多关于 Retrocomputing.SE.

的主题

无论如何,x86 奇偶校验标志对 GCC __builtin_parity() 的用处不大,因为它只测试一个字节。它可以通过将其字节异或在一起来获得更大的值,如果没有其他选择,则可以使用 GCC/clang will do this 。它通过在末尾使用 setnp 而不是 setp 来处理标志的反向意义(人类程序员只需编写 setpo 而不必考虑 set/clear标志的值)。

然而,过去 10 年几乎所有 x86 CPU 都支持 popcnt 指令和 GCC/clang will use this instead if it's available(然后只提取低位)。