使用每个单词的相应高位填充 qword 中的每个单词
Fill every word in a qword using corresponding high bit of each word
我有一个qword。它由 4 个部分组成——每个部分 16 位。
每个部分都有一个结构:每个部分的第一位不是1就是0,其他都是零。
我想用那个 16 位元素将第一位广播到所有其他位置。
在 x64 汇编中,您可以在每个单词的基础上应用算术右移:
psraw xmm0, 15
这实际上并排处理了两个这样的 qword,但您只能将其用于一个。例如,也许那个 qword 在某个地方的内存中,那么你可以这样做:
movq xmm0, [somewhere]
psraw xmm0, 15
movq [somewhere], xmm0
这也可以用于通用寄存器。
没有 SSE,即使是通用的(例如,也使用典型的高级语言中存在的操作),还有其他选择。这些都假设输入 x
具有指定的形式,没有杂散的 1,只允许每个单词的最高位为 1。上面的代码可以在其他位中包含任意垃圾。
按字面意义实现(使用实数乘法)时,它仍然只使用一个寄存器。这种转变是一种合乎逻辑的转变。在更高级的语言中,乘法可能被编译成其他东西:
(x >> 15) * 0xFFFF
可能更快,取决于乘法的成本,但需要一个临时寄存器:
(x << 1) - (x >> 15)
一种更暴力的方式,据我所知没有实际用途,但可能很有趣:
x |= x >> 8
x |= x >> 4
x |= x >> 2
x |= x >> 1
我有一个qword。它由 4 个部分组成——每个部分 16 位。
每个部分都有一个结构:每个部分的第一位不是1就是0,其他都是零。
我想用那个 16 位元素将第一位广播到所有其他位置。
在 x64 汇编中,您可以在每个单词的基础上应用算术右移:
psraw xmm0, 15
这实际上并排处理了两个这样的 qword,但您只能将其用于一个。例如,也许那个 qword 在某个地方的内存中,那么你可以这样做:
movq xmm0, [somewhere]
psraw xmm0, 15
movq [somewhere], xmm0
这也可以用于通用寄存器。
没有 SSE,即使是通用的(例如,也使用典型的高级语言中存在的操作),还有其他选择。这些都假设输入 x
具有指定的形式,没有杂散的 1,只允许每个单词的最高位为 1。上面的代码可以在其他位中包含任意垃圾。
按字面意义实现(使用实数乘法)时,它仍然只使用一个寄存器。这种转变是一种合乎逻辑的转变。在更高级的语言中,乘法可能被编译成其他东西:
(x >> 15) * 0xFFFF
可能更快,取决于乘法的成本,但需要一个临时寄存器:
(x << 1) - (x >> 15)
一种更暴力的方式,据我所知没有实际用途,但可能很有趣:
x |= x >> 8
x |= x >> 4
x |= x >> 2
x |= x >> 1