我正在维护Reko decompiler并修复其对AArch64的支持。我被要求修复AArch64二进制文件中包含以下指令的问题:
0EA0B9BF abs v31.2s,v13.2s
字符串
我已经将上面的输出(来自Reko的AArch64反汇编器)与objdump
进行了比较,并且它匹配。我已经查阅了abs
指令的ARM文档,以了解该指令的作用。
请注意,.2s
后缀意味着该指令操作两个32位有符号整数,但v31
和v13
是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模拟器崩溃了。
1条答案
按热度按时间0h4hbjxa1#
根据ARM架构参考手册(Armv 8,适用于A-profile架构),第C1.2.5节:
SIMD和浮点标量寄存器名称
对标量数据进行操作的SIMD和浮点指令只访问SIMD和浮点寄存器的低位。未使用的高位在读时被忽略,在写时被清零。
(...)
SIMD向量寄存器名称
如果一个寄存器保存了多个数据元素,并以并行SIMD方式对其执行运算,则限定符描述矢量形状。矢量形状是元素大小和元素或通道数。如果元素大小(以位为单位)乘以通道数不等于128,则在读取时忽略寄存器的高64位,在写入时清除为零。
这证实了写入64位ASIMD向量会将向量的高位清零。请注意,在AArch 32状态下,行为是不同的,其中64位和128位向量具有不同的编号方案,并且仅重叠。在那里,不存在另一半要清零,因为64位操作针对64位向量寄存器。