ARM Neon Assembler - 使用溢出寄存器

时间:2012-03-08 01:09:32

标签: assembly android-ndk arm neon

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

据我所知,如果溢出,我可以使用 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,如果这很重要的话。

2 个答案:

答案 0 :(得分: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

答案 1 :(得分: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。