2

我想做以下事情:我在 Neon D-Register (=64Bit) 中有 8 个值 (8 x 1Byte)。现在我需要将每个值 3 向左移动,但我不想丢失任何位。之后我需要将相同的 32Bit 值添加到向量中的每个值。

据我了解,如果溢出,我可以使用VQSHL指令将结果放入 2 个 D 寄存器中?我如何知道是否发生溢出并保证/强制我的所有数据都在新寄存器中?

您还可以帮我提供一些用于班次和添加部分的代码吗?

示例代码:

out0 = CONSTANT_32BIT + ( input0 << 3)

out1 = CONSTANT_32BIT + ( input1 << 3)

out_n = CONSTANT_32BIT + ( input_n << 3)

所以理论上我可以使用 Neon 寄存器并行执行 8 或 16 条这些指令?

如果这很重要,目标是 ARM Cortex-A9。

4

2 回答 2

3

你可以做这样的事情(未经测试的代码,但应该让你知道如何去做):

//Assumes signed ints
//d0: 8 input bytes
//q3: contains four copies of the 32-bit constant
//Perform shift and extend to 16-bit elements
vshll.s8 q0, d0, #3
//Extend 16-bit elements to 32-bit elements and add the 32-bit constants
vaddw.s16 q1, q3, d0
vaddw.s16 q2, q3, d1
//q1 now contains first four values, q2 the last four
于 2012-03-08T09:16:28.913 回答
2

VQSHL是一个饱和转变。也就是说,它不会让通道溢出,如果它们溢出,它们将饱和到最大可能值。如果这是所需的行为,那么这对您有用。如果发生饱和,处理器将设置FPSCR.QC(累积饱和标志)。

根据您的描述,听起来您不想要溢出行为。如果您计划为每个 8 位值添加一个 32 位值,则结果通常不适合 8 位寄存器。也许您应该考虑将 8 位值加载到更宽的寄存器中。例如 4 个 32 位通道。您可以使用 VLD 的多元素形式来帮助您将 8 位值加载到 NEON 寄存器中,例如VLD2.8 {d0[0],d1[0],d2[0],d3[0]}, [r0]将加载偶数索引,然后您可以加载奇数索引。另一种选择是使用 VZIP。

于 2012-03-08T03:25:50.937 回答