【ARMv8/ARMv9 硬件加速系列 2.2 -- ARM NEON 的加减乘除(左移右移)运算】

发布于:2024-06-23 ⋅ 阅读:(52) ⋅ 点赞:(0)

文章目录

NEON 加减乘除

下面代码是使用ARMv8汇编语言对向量寄存器v0-v31执行加、减、乘以及左移和右移操作的示例。
ARMv8的SIMD指令集允许对向量寄存器中的多个数据进行并行操作。v0v1加载数据,对它们进行加、减和乘,左移和右移操作。最后,我们会将结果存储到内存地址0xb0000000处, 方便观察结果。

func neon_calc_test
    stp	    x29, x30, [sp, #-0x10 * 1]!

    // add
    mov w0, #0x1111
    mov v0.s[0], w0
    mov v1.s[0], w0
    fadd v2.4s, v0.4s, v1.4s    // v2 = v0 + v1

    // sub
    mov w0, #0x2222
    mov v0.s[0], w0
    mov w0, #0x1111
    mov v1.s[0], w0
    fsub v3.4s, v0.4s, v1.4s    // v3 = v0 - v1

    // multi
    mov w0, #0xf
    mov v0.s[0], w0
    mov w0, #0x11
    mov v1.s[0], w0
    mul v4.4s, v0.4s, v1.4s    // v4 = v0 * v1

    // left shift
    movi v0.4s, #0xff
    shl v5.4s, v0.4s, #1        // v5 = v2 << 1 (每个元素左移1)

    // right shift
    movi v0.4s, #0xff
    srshr v6.4s, v0.4s, #1        // v6 = v3 >> 1 (每个元素右移1)

    mov x0, xzr
    ldr x0, =0xb0000000
    st1 {v2.4s}, [x0], #16    // 发送v2到内存,并将x0增加16
    st1 {v3.4s}, [x0], #16    // 发送v3到内存,并将x0增加16
    st1 {v4.4s}, [x0], #16    // 发送v4到内存,并将x0增加16
    st1 {v5.4s}, [x0], #16    // 发送v5到内存,并将x0增加16
    st1 {v6.4s}, [x0]         // 发送v6到内存
    ldp x29, x30, [sp], #0x10
    ret
endfunc neon_calc_test
  • 首先,我们使用fadd, fsub, 和 mul指令对浮点数进行加、减、乘操作,结果分别存储在v2, v3, 和 v4中。
  • 然后,使用shlsrshr指令对整数进行左移和右移操作,结果存储在v5v6中。
  • 最后,我们使用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

网站公告

今日签到

点亮在社区的每一天
去签到