【发布时间】:2021-06-02 10:20:32
【问题描述】:
我有两个 64 位值,我想按如下方式对它们进行 XNOR:
RAX: 01000001 | 01000010 | 01000011 | 01000001 | 01000101 | 01000110 | 01000111 | 01000001 XNOR
RBX: 01000001 | 01000001 | 01000001 | 01000001 | 01000001 | 01000001 | 01000001 | 01000001
-------------------------------------------------------------------------------------------
RCX: 1 0 0 1 0 0 0 1
XNOR does the following:
1 XNOR 1 | 1
1 XNOR 0 | 0
0 XNOR 1 | 0
0 XNOR 0 | 1
这样每次 XNOR 的结果正好是 0xff 它在 RCX 寄存器中的相应块位置输出 1。
是否有 I64 指令或算术/逻辑表达式来解决上述问题?
【问题讨论】:
-
这可能更好地表示为矢量比较,
pcmpeqb非常接近您想要的。这将在比较相等的字节中留下0xff,而不是0x1,所以也许你在它后面跟着一个向量否定;我不确定是否只有一条指令,但是从 0 中减去向量就可以了。 -
所以 XNOR 只是一个相等比较?
-
XNOR 在位级别上是相等的,是的(参见真值表)。但是您想要的并不是真正的按位 XNOR,因为您希望示例中的第二个字节为 0 而不是
11111100。所以我真的认为这是一个 bytewise 操作,而不是按位操作,从这个意义上说,将其称为比较比 XNOR 更有意义。这也向我表明 SIMD 是一条比 bit twiddling 更好的途径。 -
@NateEldredge:
pabsb(字节绝对值)将映射 0xff -> 1 和 0x00 -> 0。但如果他们想要 RCX 中的结果,他们可能希望pmovmskb ecx, xmm0提取高每个向量字节的位,给出比较结果的位图。除非他们想要每个字节用零分隔 1 位。 -
相关:Compare 16 byte strings with SSE 使用内在函数。使用
movq加载(或从整数 reg 注册副本)而不是movdqu仅加载 8 个字节,如果这真的是你想要的。
标签: assembly bit-manipulation x86-64 simd