ARM NEON汇编程序 - 用法&理解

时间:2012-02-16 17:36:15

标签: android assembly arm neon armv6

我是汇编程序和NEON编程的新手。 我的任务是使用NEON指令将部分算法从C转换为ARM Assembler。 该算法采用int32数组,从该数组加载不同的值,执行一些位移和Xor并将结果写入另一个数组。 稍后我将使用64位值的数组,但是现在我只是尝试重写代码。

C Pseudo code:

out_array[index] = shiftSome( in_array[index] ) ^ shiftSome( in_array[index] );

以下是关于NEON指令的问题:

1。)如果我加载这样的寄存器:

vld1.32 d0, [r1]

它只从内存加载32Bit或2x32Bit来填充64Bit Neon D-Register吗?

2.。)如何访问D-Register的2/4/8(i32,i16,i8)部分?

3。)我试图从数组中加载带偏移量的不同值,但事实并非如此 似乎工作......我做错了什么......这是我的代码: (它是一个整数数组,所以我试图加载例如3元素,它应该有64Bit = 8 Byte的偏移量)

asm volatile(
"vld1.32 d0, [%0], #8 \n"     
"vst1.32 d0, [%1]" : : "r" (a), "r" (out): "d0", "r5");

其中“a”是数组,“out”是指向整数的指针(用于调试)。

4.。)我从数组加载一个值后,我需要将它移到右边,但它似乎不起作用:

vshr.u32 d0, d0, #24     // C code:   x >> 24;

5.。)是否可以只在霓虹灯寄存器中加载1个字节,这样我就不必移动/屏蔽某些东西只能得到我需要的一个字节?

6。)我需要使用Inline汇编程序,但我不确定最后一行是什么:

input list : output list : what is this for?

7。)你知道任何带有代码示例的NEON参考资料吗?

该程序应该在Samsung Galaxy S2,cortex-A9处理器上运行,如果这有任何区别的话。谢谢你的帮助。

----------------编辑-------------------

这就是我发现的:

  1. 它将始终加载完整的Register(64Bit)
  2. 您可以使用“vmov”指令将部分氖寄存器传输到arm寄存器。
  3. 偏移量应该在一个手臂寄存器中,并且会被添加到 基本地址 内存访问后。
  4. 这是“破坏的登记名单”。每个使用的注册表和 在输入或输出列表中都不应该写在这里。

2 个答案:

答案 0 :(得分:10)

我可以回答你的大多数问题:(更新:澄清“泳道”问题)

1)NEON指令一次只能加载和存储整个寄存器(64位,128位)。 MOV指令变体允许将单个“通道”移入或移出ARM寄存器。

2)您可以使用NEON MOV指令影响单个通道。在执行太多单个元素操作时,性能将受到影响。 NEON指令通过对向量(浮点数/整数组)进行并行运算来提高应用程序性能。

3)ARM汇编语言中的立即值偏移量是字节,而不是元素/寄存器。 NEON指令允许使用寄存器进行后递增,而不是立即值。对于普通的ARM指令,后递增8将向源指针添加8(字节)。

4)NEON中的移位会影响向量的所有元素。使用vshr.u32的24位右移将使32位无符号长整数移位24位,并丢弃移出的位。

5)NEON指令允许将单个元素移入和移出普通ARM寄存器,但不允许从内存中直接加载或存储到“通道”。

6)?

7)从这里开始:http://blogs.arm.com/software-enablement/161-coding-for-neon-part-1-load-and-stores/ ARM网站有一个很好的NEON教程。

答案 1 :(得分:0)

6)Clobbered寄存器。

asm(code : output operand list : input operand list : clobber list);

如果您使用的寄存器尚未作为操作数传递,则需要通知 关于这个的编译器。以下代码将值调整为四的倍数。它 使用r3作为临时寄存器,让编译器通过在中指定r3来了解这一点 clobber列表。此外,CPU状态标志由ands指令修改。 将伪寄存器cc添加到clobber列表将使编译器了解情况 这个修改也是如此。

asm (
"ands R3, %1, #3"
"eor %0, %0, r3"
: "=r"(len)
: "0"(len)
: "cc", "r3"
);