ARM NEON 到 aarch64
Posted
技术标签:
【中文标题】ARM NEON 到 aarch64【英文标题】:ARM NEON to aarch64 【发布时间】:2020-08-24 13:40:16 【问题描述】:我有 ARM NEON armv7-a 的代码:
vst2.u8 d1,d3, [%1]!
我像这样将它移植到 aarch64:
st2 v1.8b,v3.8b,[%1],#16
得到一个错误:错误:操作数 1 的寄存器列表无效 -- `st2 v1.8b,v3.8b,[x1],#16'
根据文档,这是有效的:
ST2 Vt.<T>, Vt+2.<T>, vaddr
我无法找出问题所在。
附言如果我改变它像
st2 v1.8b,v2.8b,[%1],#16
编译器不会因错误消息而中断
【问题讨论】:
您在看哪个文档? ARM® A64 指令集架构 (DDI 0596) 表示:<Vt> Is the name of the first or only SIMD&FP register to be transferred, encoded in the "Rt" field. <Vt2> Is the name of the second SIMD&FP register to be transferred, encoded as "Rt" plus 1 modulo 32.
@Michael,我在看this 和this 文件
d1,d3
是 32 位模式下 2 个连续 16 字节 q
寄存器的高 64 位。 v1.8b
和 v2.8b
是 64 位模式下 2 个连续 16 字节向量寄存器的低 64 位。 (我没有检查 32 位指令是否可以对任意对进行编码,或者在 32 位模式下只能对 reg、reg+2 进行编码)
【参考方案1】:
我这里指的是ARM a64 instruction set architecture,最后一次更新是在2018年。
您评论中的第一个链接仅涉及 aarch32 指令集。第二个链接是关于 aarch64 指令集的,但它在 pdf 标题中的标题为 iterim,并于 2011 年发布。格式
ST2 <Vt>.<T>, <Vt+2>.<T> , vaddr
在此提及(第 89 页),但当前版本中不包含此内容。
ST2
的编码
在当前版本中,ST2
针对多种数据结构进行编码如下(参见第 1085 页):
┌───┬───┬──────────┬───┬───────┬──────┬────┬───────┬───────┐
│ 0 │ Q │ 00110010 │ I │ mmmmm │ 1000 │ ss │ nnnnn │ ttttt │
└───┴───┴──────────┴───┴───────┴──────┴────┴───────┴───────┘
Rm size Rn Rt
指令可以使用三种类型的偏移:
无偏移(Rm == 000000
和 I == 0
):
ST2 <Vt>.<T>, <Vt2>.<T> , [<Xn|SP>]
立即偏移(Rm == 111111
和 I == 1
):
ST2 <Vt>.<T>, <Vt2>.<T> , [<Xn|SP>], <imm>
注册偏移量(Rm != 111111
和 I == 1
):
ST2 <Vt>.<T>, <Vt2>.<T> , [<Xn|SP>], <Xm>
<imm>
在这里是#16
或#32
,关于Q
。这里的编码中只保存了第一个寄存器的索引t
。第二个寄存器的索引始终计算为t+1 mod 32
。
这就是你得到错误的原因:寄存器必须彼此跟随。根本没有足够的空间来单独编码第二个寄存器。这两个变址寄存器已经占用太多空间了。
考虑
难道不能对第二个寄存器进行编码吗?在I == 0
的情况下,Rm
设置为00000
,但这只是常规的。该寄存器可以用于我们的目的,但仅限于没有指定立即数或寄存器偏移量的情况。
我也看到了草案中没有采用<Vt+2>
格式的原因:它只能针对这种特殊情况进行编码。该实现将使芯片的实现更加复杂,根本不值得。
【讨论】:
以上是关于ARM NEON 到 aarch64的主要内容,如果未能解决你的问题,请参考以下文章
Aarch64 NEON 中的 UADDL 与 UADDL2
Debug系列aarch64下unrecognized command line option ‘-mfpu=neon‘
优化系列汇编优化技术:ARM架构64位(AARCH64)汇编优化及demo