assembly AArch 64 SIMD指令零/符号扩展结果吗?

oiopk7p5  于 11个月前  发布在  其他
关注(0)|答案(1)|浏览(157)

我正在维护Reko decompiler并修复其对AArch64的支持。我被要求修复AArch64二进制文件中包含以下指令的问题:

0EA0B9BF abs v31.2s,v13.2s

字符串
我已经将上面的输出(来自Reko的AArch64反汇编器)与objdump进行了比较,并且它匹配。我已经查阅了abs指令的ARM文档,以了解该指令的作用。
请注意,.2s后缀意味着该指令操作两个32位有符号整数,但v31v13是128位的。我最初的猜测是该指令保留了v31的高64位不变,但我不确定我的解释是否正确。参考经文揭示了abs的以下伪代码:

CheckFPAdvSIMDEnabled64();
 bits(datasize) operand = V[n];
 bits(datasize) result;
 integer element;

 for e = 0 to elements-1
 element = SInt(Elem[operand, e, esize]);
 if neg then
   element = -element;
 else
   element = Abs(element);
 Elem[result, e, esize] = element<esize-1:0>;

V[d] = result;


在伪代码中,result变量没有用V[d]的原始值初始化,而是在最后一个伪语句中写回整个128位。
于是:result实际上是zero-initialized,这意味着在执行此指令后,高64位被清除?这是否适用于所有输出不“覆盖”目标SIMD寄存器的全部128位的SIMD指令?
不幸的是,我没有合适的芯片来测试这个,当我尝试使用SIMD指令时,可用的AArch64模拟器崩溃了。

0h4hbjxa

0h4hbjxa1#

根据ARM架构参考手册(Armv 8,适用于A-profile架构),第C1.2.5节:

SIMD和浮点标量寄存器名称

对标量数据进行操作的SIMD和浮点指令只访问SIMD和浮点寄存器的低位。未使用的高位在读时被忽略,在写时被清零。
(...)

SIMD向量寄存器名称

如果一个寄存器保存了多个数据元素,并以并行SIMD方式对其执行运算,则限定符描述矢量形状。矢量形状是元素大小和元素或通道数。如果元素大小(以位为单位)乘以通道数不等于128,则在读取时忽略寄存器的高64位,在写入时清除为零。
这证实了写入64位ASIMD向量会将向量的高位清零。请注意,在AArch 32状态下,行为是不同的,其中64位和128位向量具有不同的编号方案,并且仅重叠。在那里,不存在另一半要清零,因为64位操作针对64位向量寄存器。

相关问题