5

我无法区分ARM NEON 指令vld4_f32之间的区别。vld4q_f32

当我提高编码水平并开始查看汇编指令而不是信息量较少的内在函数时,困惑就开始了。

我需要在这里使用vld4变体指令的原因是,我想从我的大数组的每4 个位置捕获4 个。 float32_t

替代文字

内在函数和相应的vld4_f32汇编指令如下所示(来自此链接

float32x2x4_t vld4_f32 (const float32_t *) 
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0]

vld4q_f32内在函数及其相应的汇编指令如下所示

float32x4x4_t vld4q_f32 (const float32_t *) 
Form of expected instruction(s): vld4.32 {d0, d1, d2, d3}, [r0]

好吧,在内部函数级别,我看到的区别是返回类型,但是如果我查看汇编指令和寄存器的数量,它们看起来都一样。编译器或汇编器如何知道两者之间的区别?

有人可以对此进行更多澄清并解释我如何将位于每个第 4 个内存位置的4 个 float32_t值加载到单个寄存器中吗?

4

2 回答 2

7

是的,我发现了不同之处。我使用 CodeSourcery 查看所有加载指令的实际寄存器内容。我发布的链接没有提供有关 vld4q_f32 的完整详细信息。

好的,首先是vld4_f32,这会加载4 个 d寄存器(例如 d16-19),每个d寄存器都是 64 位长,因此该指令将加载前 8 个值,间隔为 4,如下图所示。 替代文字

在第二种情况下vld4q_f32,这将加载8 个 d寄存器(例如 d16-23)而不是 4 个。对于这个链接的读者来说,完全不清楚是否会加载 8 个寄存器。当我查看 a 的反汇编代码时vld4qf32,它使用了 8 个 d 寄存器。

这条指令确实会做我希望它做的事情,即加载 4 个float32_t间隔为 4 的值,如下图所示。 替代文字

于 2010-09-29T12:13:10.370 回答
2

我已经反汇编了两个内在函数,也许它对某人有帮助:

// C++
uint32x4x4_t r = vld4q_u32( ( uint32_t *) output );
// assembly
VLD4.32         {D16,D18,D20,D22}, [R0]!
VLD4.32         {D17,D19,D21,D23}, [R0]

// C++
uint32x2x4_t r = vld4_u32( ( uint32_t *) output );
// assembly
VLD4.32         {D20-D23}, [R0]
于 2011-04-23T16:22:33.207 回答