SSE 到霓虹灯 (_mm_movelh_ps)
SSE to Neon (_mm_movelh_ps)
我正在将一些 SSE 代码移至 Neon,但我找不到任何与 _mm_movelh_ps 等效的代码。我 google 找不到任何东西...我是不是遗漏了什么?是否有任何 Neon 功能做同样的事情,或者我将不得不在 CPU 上实现它(不理想)。
提前致谢!
SSE 有 128 位向量寄存器 ("xmmN"
)。 _mm_movelh_ps()
从向量寄存器的低 64 位传输到向量寄存器的高 64 位。
ARM32 NEON 具有 64 位向量寄存器 ("dN"
)。两个连续的向量寄存器,其中第一个是偶数,可以组合成一个 128 位向量寄存器("qN"
)。
要在 ARM32 NEON 中获得 _mm_movelh_ps
的功能,您可以使用普通的 64 位向量移动。
#include <immintrin.h>
__m128 foo(__m128 a, __m128 b)
{
return _mm_movelh_ps(a, b);
}
相当于下面的gcc vector intrinsics
typedef float v4sf __attribute__((vector_size(16)));
typedef unsigned v4ui __attribute__((vector_size(16)));
v4sf bar(v4sf a, v4sf b)
{
return __builtin_shuffle(a, b, (v4ui){0, 1, 4, 5});
}
在我的 gcc 4.8.4 上都编译成相同的代码:
movlhps %xmm1, %xmm0
ret
不幸的是,ARM32 NEON 的 gcc 4.9.2 产生了可笑的错误代码:
vldr d16, .L2
vldr d17, .L2+8
vtbl.8 d18, {d0, d1, d2, d3}, d16
vtbl.8 d19, {d0, d1, d2, d3}, d17
vmov q0, q9 @ v16qi
bx lr
因此您可能需要使用 NEON 内在函数:
#include <arm_neon.h>
float32x4_t foo(float32x4_t a, float32x4_t b)
{
return vcombine_f32(vget_low_f32(a), vget_low_f32(b));
}
编译为预期的简单移动指令:
vmov d1, d2 @ v2sf
bx lr
我正在将一些 SSE 代码移至 Neon,但我找不到任何与 _mm_movelh_ps 等效的代码。我 google 找不到任何东西...我是不是遗漏了什么?是否有任何 Neon 功能做同样的事情,或者我将不得不在 CPU 上实现它(不理想)。
提前致谢!
SSE 有 128 位向量寄存器 ("xmmN"
)。 _mm_movelh_ps()
从向量寄存器的低 64 位传输到向量寄存器的高 64 位。
ARM32 NEON 具有 64 位向量寄存器 ("dN"
)。两个连续的向量寄存器,其中第一个是偶数,可以组合成一个 128 位向量寄存器("qN"
)。
要在 ARM32 NEON 中获得 _mm_movelh_ps
的功能,您可以使用普通的 64 位向量移动。
#include <immintrin.h>
__m128 foo(__m128 a, __m128 b)
{
return _mm_movelh_ps(a, b);
}
相当于下面的gcc vector intrinsics
typedef float v4sf __attribute__((vector_size(16)));
typedef unsigned v4ui __attribute__((vector_size(16)));
v4sf bar(v4sf a, v4sf b)
{
return __builtin_shuffle(a, b, (v4ui){0, 1, 4, 5});
}
在我的 gcc 4.8.4 上都编译成相同的代码:
movlhps %xmm1, %xmm0
ret
不幸的是,ARM32 NEON 的 gcc 4.9.2 产生了可笑的错误代码:
vldr d16, .L2
vldr d17, .L2+8
vtbl.8 d18, {d0, d1, d2, d3}, d16
vtbl.8 d19, {d0, d1, d2, d3}, d17
vmov q0, q9 @ v16qi
bx lr
因此您可能需要使用 NEON 内在函数:
#include <arm_neon.h>
float32x4_t foo(float32x4_t a, float32x4_t b)
{
return vcombine_f32(vget_low_f32(a), vget_low_f32(b));
}
编译为预期的简单移动指令:
vmov d1, d2 @ v2sf
bx lr