如何在ARMv7 NEON向量间移动单字数据
ARMv7 NEON:无需通用寄存器的跨向量单元素复制方案
嘿,这个问题我之前在优化ARMv7 NEON汇编代码的时候也碰到过!确实ARMv7 NEON指令集里没有直接的mov dm[x], dn[y]这类跨向量单元素移动指令,但有几个完全不用通用寄存器(r寄存器)中转的方案可以满足你的需求,下面分情况说明:
情况1:目标向量的所有元素都需要设为源元素的值
如果你的需求是把源向量的某个32位元素复制到目标向量的所有位置,直接用vdup.32指令就可以搞定,这是最简洁的方式:
@ 示例:把q0的第1个32位元素(对应d1寄存器的第0个元素)复制到q1的所有4个32位位置 vdup.32 q1, d1[0]
这里的d1是源向量q0的高64位寄存器,d1[0]就是q0[1]这个32位元素;q1是目标向量寄存器,执行后它的所有4个32位元素都会等于q0[1]的值。
情况2:仅替换目标向量的特定位置,其他元素保留原值
如果只想修改目标向量的单个位置(比如你的dm[0]),同时保留其他元素的原始值,可以用vdup+vbsl的组合方案,全程用NEON指令完成:
@ 示例:把q0[1]复制到q1[0],q1的其他元素保持不变 1. 生成掩码向量:q2的第0个元素为0,其余为全1(用于标记要替换的位置) vmov.i32 q2, #-1 @ 先把q2所有元素初始化为0xFFFFFFFF vmov.i32 d4[0], #0 @ 将q2的第0个元素设为0(d4是q2的低64位寄存器) 2. 把源元素复制为全元素向量:q3的所有元素都是q0[1]的值 vdup.32 q3, d1[0] 3. 用位选择指令完成替换:掩码为1的位置保留q1原值,为0的位置取q3的源元素值 vbsl.32 q1, q2, q3
情况3:可以接受源元素位置的原值被覆盖(交换操作)
如果你的需求只是让dm[0]等于dn[1],并且不在乎dn[1]的原始值被dm[0]覆盖,那么vswp指令是最优选择——它直接完成跨寄存器的单元素交换,完全不需要额外寄存器中转:
@ 示例:交换q1[0]和q0[1]的值,执行后q1[0]就等于原来的q0[1] vswp.32 q1[0], q0[1]
以上所有指令都是ARMv7 NEON标准支持的,不需要依赖ARMv8的扩展指令,完全符合你不用通用寄存器的要求。
内容的提问来源于stack exchange,提问作者A23149577
相关产品推荐
相关产品推荐

