我是汇编程序和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处理器上运行,如果这有任何区别的话。谢谢你的帮助。
----------------编辑-------------------
这就是我发现的:
答案 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"
);