问题描述
我有用于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
我无法解决问题。
p.s。如果我将其更改为
st2 {v1.8b,v2.8b},#16
编译器不会出现错误消息
解决方法
我在这里指的是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>,[<Xn|SP>],<imm>
-
寄存器偏移量(
Rm != 111111
和I == 1
):ST2 { <Vt>.<T>,<Xm>
<imm>
, #16
是#32
或Q
。此处仅将第一个寄存器的索引t
保存在编码中。第二个寄存器的索引始终按t+1 mod 32
计算。
这就是为什么您会收到错误消息:寄存器必须彼此跟随。根本没有足够的空间来单独编码第二个寄存器。这两个索引寄存器已经占用太多空间。
注意事项
是否可以对第二个寄存器进行编码?在I == 0
的情况下,Rm
设置为00000
,但这只是常规做法。该寄存器可以用于我们的目的,但是仅在未指定立即数或寄存器偏移量的情况下。
我还看到了草案中未采用<Vt+2>
格式的原因:只能为这种特殊情况编码。该实现将使芯片的实现更加复杂并且根本不值得。