22.3 NEON指令集
在 NEON 指令集中,指令通常可以分成两大类:一类是矢量(vector)运算指令;另一类是标量(scalar)运算指令。矢量运算指的是对矢量寄存器中所有通道的数据同时进行运算,而标量运算指的是只对矢量寄存器中某个通道的数据进行运算。
22.3.1 SISD与SIMD
SISD指的是单指令但数据,SIMD指的是单指令多数据,他能同时对多个数据元素执行相同的操作。SIMD非常适合做图像处理
22.3.2 矢量运算与标量运算
NEON指令集可以分为矢量指令集和标量指令集。
矢量运算指的是对矢量寄存器中所有通道的数据同时进行运算,而标量运算指的是只对矢量寄存器中某个通道的数据进行运算。
22.3.3 加载与存储指令
22.3.3.1 LD1与ST1
LD1 指令用来把多个数据元素加载到 1 个、2 个、3 个或 4 个矢量寄存器中。
LD1 指令最多可以使用 4 个矢量寄存器。
LD1 指令支持没有偏移量和后变基两种模式。
没有偏移量模式的指令格式如下。
LD1 { <Vt>.<T> }, [<Xn|SP>]
LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
后变基模式的 ST1 指令格式如下。
LD1 { <Vt>.<T> }, [<Xn|SP>], <imm>
LD1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
LD1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
上述指令表示从 Xn/SP 指向的源地址中加载多个数据元素到 Vt、Vt2、Vt3 以及 Vt4 矢量寄存器中,加载的数据类型由矢量寄存器的 T 来确定,加载完成之后,更新 Xn/SP 寄存器的值为 Xn/SP 寄存器的值加 imm。
与 LD1 对应的存储指令为 ST1。
ST1 指令把 1 个、2 个、3 个或 4 个矢量寄存器的多个数据元素的内容存储到内存中。
ST1 指令最多可以使用 4 个矢量寄存器。
ST1 指令支持没有偏移量和后变基两种模式。
没有偏移量模式的指令格式如下。
ST1 { <Vt>.<T> }, [<Xn|SP>]
ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>]
ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>]
ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>]
后变基模式的 ST1 指令格式如下。
ST1 { <Vt>.<T> }, [<Xn|SP>], <imm>
ST1 { <Vt>.<T>, <Vt2>.<T> }, [<Xn|SP>], <imm>
ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T> }, [<Xn|SP>], <imm>
ST1 { <Vt>.<T>, <Vt2>.<T>, <Vt3>.<T>, <Vt4>.<T> }, [<Xn|SP>], <imm>
上述指令表示把 Vt、Vt2、Vt3 以及 Vt4 矢量寄存器的数据元素存储到 Xn/SP 指向的内存地址中,数据类型由矢量寄存器的 T 来确定,存储完成之后,更新 Xn/SP 寄存器的值为 Xn/SP寄存器的值加 imm。
22.3.3.2 LD2与ST2
LD1 和 ST1 指令按照内存顺序来加载和存储数据,而有些场景下希望能按照**交替(interleave)**的方式来加载和存储数据。L