学习 GCC ASM:SSE 到 NEON:加载和存储

Posted

技术标签:

【中文标题】学习 GCC ASM:SSE 到 NEON:加载和存储【英文标题】:Learning GCC ASM: SSE to NEON: Loads and Stores 【发布时间】:2012-12-05 16:54:58 【问题描述】:

我有一段使用 SSE 指令编写的内联 ASM 代码,我需要将其移植到 NEON。我想自己学习基础知识,看看我能不能一步一步地完成,而不是把整个东西批量转换。

因此,第一步是学习加载和存储。考虑...

float input[4] =  1.0f, 2.0f, 3.0f, 4.0f ;
float output[4] =  0 ;
asm volatile
(
    "movups %[I], %%xmm0 \n\t"
    "movups %%xmm0, %[O] \n\t"
    : [O] "=m" (output[0])
    : [I] "m" (input[0])
    : "memory", "xmm0"
);

我知道(我认为)我应该使用 vld1.32 指令,但我对将它与我之前使用过的其他一些 GCC ASM 构造(如命名变量等)结合起来有点含糊。 )。

【问题讨论】:

【参考方案1】:
vld1.32 d0,d1, [%[I]]; 
vst1.32 q0, [%[O]];   

根据 gcc 版本,它将 q0 识别为 d0,d1。 另外我认为你想要 (&output[0]) 或简单地 (output) 和 (input) 而不是将浮点数加载到通用寄存器。

在 ARM 中,您还可以后递增指针:xxx , [%[I]!]

咨询例如例如this。

【讨论】:

事实证明,约束也需要一些调整。 "vld1.32 d0,d1, [%[I]] \n\t" "vst1.32 d0,d1, [%[O]] \n\t" : : [I] "r" (input), [O] "r" (output) : "memory", "d0", "d1" 确实如此。还有一些 gcc 版本在 clobber 列表中需要 "d0"、"d1" 和 "q0"。

以上是关于学习 GCC ASM:SSE 到 NEON:加载和存储的主要内容,如果未能解决你的问题,请参考以下文章

SSE (Intel) 到 NEON (ARM) 数据类型类似物

NEON、SSE 和交错负载与随机播放

从 SSE 到 ARM Neon 的指令转换

SSE 将整数加载到 __m128

将 SSE2 迁移到 Arm NEON 内部函数

为啥要在 ASM 中指定变量的地址而不是将其复制到寄存器中?