aarch64内联汇编堆栈指针约束内存地址,包含Clang 6+的偏移量

问题描述 投票:0回答:1

我注意到在不同的优化级别,Clang 6有时使用ldp(负载氖寄存器对)用于相邻的存储器地址vld1 neon load instrinsics。

我正在尝试使用内联汇编来手动强制执行更多的加载对指令。源数组保存在堆栈中,当Clang本身生成ldp指令时,它使用带偏移量的堆栈指针,但是当我使用带有内联汇编的索引进入数组时,它会扩展为x寄存器以获取地址。然而,这会导致性能下降。我相信这是因为从堆栈读取速度更快但是作为源地址的ax寄存器可能指向堆,而堆可能反过来引用回堆栈,虽然我不确定,或者它可能是从堆中的重复数据读取。这是我现在使用的一个例子。

asm (
    "ldp %q[DST1], %q[DST2], [%[SRC]]" "\n"
    : [DST1] "=w" (TMP1), [DST2] "=w" (TMP2)
    : [SRC] "X" (&K2[8])
);

这就是Clang将其扩展到的内容

ldp q19, q4, [x11]

但是我想使用带有偏移地址的堆栈指针,从索引的K2数组变量中自动解析。例如

ldp q19, q4, [sp,#32]

反汇编代码中堆栈指针地址的偏移量不相邻,因此我不能仅对sp寄存器进行硬编码并输入偏移量来加载顺序数据。这是因为Clang 6正在将其他函数使用的其他数组中的相同值合并到堆栈中。

GCC有aarch64机器约束,比如k用于堆栈指针(sp)寄存器,Ump用于stp和ldp存储/加载对指令地址,我从来没有在GCC或Clang上工作,后者没有等效约束在稀疏的文档中。

我倾向于使用Clang 6,因为它生成的代码比GCC 8快6%,因为它正在将性能关键循环中的大多数指令安排到双重问题中。

无论如何输入一个数组,索引作为内联汇编的输入,让它自动解析为Clang 6中带偏移地址的堆栈指针?

stack clang inline-assembly memory-address arm64
1个回答
1
投票

您是否尝试过使用像[SRC] "m" (K2[8])这样的内存源操作数?没有它,你甚至没有告诉编译器内存内容也是内联asm的输入,所以它可能会重新排序你的asm wrt。商店,或做死店消除。

让编译器选择寻址模式是"m"操作数的全部要点。

© www.soinside.com 2019 - 2024. All rights reserved.