文章目录
- NEON 加减乘除
NEON 加减乘除
下面代码是使用ARMv8汇编语言对向量寄存器v0-v31
执行加、减、乘以及左移和右移操作的示例。
ARMv8的SIMD指令集允许对向量寄存器中的多个数据进行并行操作。v0
和v1
加载数据,对它们进行加、减和乘,左移和右移操作。最后,我们会将结果存储到内存地址0xb0000000
处, 方便观察结果。
func neon_calc_teststp x29, x30, [sp, #-0x10 * 1]!// addmov w0, #0x1111mov v0.s[0], w0mov v1.s[0], w0fadd v2.4s, v0.4s, v1.4s // v2 = v0 + v1// submov w0, #0x2222mov v0.s[0], w0mov w0, #0x1111mov v1.s[0], w0fsub v3.4s, v0.4s, v1.4s // v3 = v0 - v1// multimov w0, #0xfmov v0.s[0], w0mov w0, #0x11mov v1.s[0], w0mul v4.4s, v0.4s, v1.4s // v4 = v0 * v1// left shiftmovi v0.4s, #0xffshl v5.4s, v0.4s, #1 // v5 = v2 << 1 (每个元素左移1位)// right shiftmovi v0.4s, #0xffsrshr v6.4s, v0.4s, #1 // v6 = v3 >> 1 (每个元素右移1位)mov x0, xzrldr x0, =0xb0000000st1 {v2.4s}, [x0], #16 // 发送v2到内存,并将x0增加16st1 {v3.4s}, [x0], #16 // 发送v3到内存,并将x0增加16st1 {v4.4s}, [x0], #16 // 发送v4到内存,并将x0增加16st1 {v5.4s}, [x0], #16 // 发送v5到内存,并将x0增加16st1 {v6.4s}, [x0] // 发送v6到内存ldp x29, x30, [sp], #0x10ret
endfunc neon_calc_test
- 首先,我们使用
fadd
,fsub
, 和mul
指令对浮点数进行加、减、乘操作,结果分别存储在v2
,v3
, 和v4
中。 - 然后,使用
shl
和srshr
指令对整数进行左移和右移操作,结果存储在v5
和v6
中。 - 最后,我们使用
st1
指令将结果依次写入到内存地址0x87000000
处。
请注意,
st1
指令使用了后置更新地址的写法,每次存储后都会更新x0
寄存器的值,为下一次存储准备。
测试结果:
msh >dump 0xb0000000 20
0xb0000000: 0x00002222 0x00000000 0x00000000 0x00000000
0xb0000010: 0x00001111 0x00000000 0x00000000 0x00000000
0xb0000020: 0x000000ff 0x00000000 0x00000000 0x00000000
0xb0000030: 0x000001fe 0x000001fe 0x000001fe 0x000001fe
0xb0000040: 0x00000080 0x00000080 0x00000080 0x00000080