1

假设我在霓虹灯中有一个 64 位 d 寄存器。假设它存储值 ABCDEFGH。现在我想添加 A&E、B&F、C&G、D&H 等等。这里有任何内在的东西可以进行这样的操作吗

我查看了文档,但没有找到合适的东西。

4

1 回答 1

1

如果要在 16 位中进行加法,即产生 uint16x4 结果,可以使用 vmovl 将输入向量从 uint8x8 提升为 uint8x16,然后使用 vadd 将下半部分和上半部分相加。用 NEON 内在函数表示,这是通过以下方式实现的

const int16x8_t t = vmovl_u8(input);
const int16x4_t r = vadd_u16(vget_low(t), vget_high(t))

这应该编译为以下程序集(d0 是 64 位输入寄存器,d1 是 64 位输出寄存器)。注意 vget_low 和 vget_high 不产生任何指令——这些内在函数是通过适当的寄存器分配实现的,通过利用 Q 寄存器只是命名两个连续 D 寄存器的便捷方式。Q{n} 指的是对 (D{2n}, D{2n+1})。

VMOVL.U8 q1, d0
VADD.I16 d1, d2

如果您希望操作以 8 位执行,并在溢出的情况下饱和,请执行

const int8x8_t t = vreinterpret_u8_u64(vshr_n_u64(vreinterpret_u64_u8(input), 32));
const int8x8_t r = vqadd_u8(input, t);

这编译为(d0 再次是输入,在 d1 中输出)

VSHR.U64 d1, d0, #32
VQADD.I8 d1, d0

通过仅用 VADD 替换 VQADD,结果将在溢出时回绕,而不是饱和到 0xff。

于 2012-08-31T10:48:08.513 回答