问题描述
和类似的* _epi64指令似乎使用并依赖于 __ m64
类型。我想初始化一个 __ m128
类型的变量,使它的高64位为0,低64位设置为 x
,其中 x
的类型为 uint64_t
(或类似的无符号64位类型)。
The _mm_set_epi64
and similar *_epi64 instructions seem to use and depend on __m64
types. I want to initialize a variable of type __m128
such that the upper 64 bits of it are 0, and the lower 64 bits of it are set to x
, where x
is of type uint64_t
(or similar unsigned 64-bit type). What's the "right" way of doing so?
最好是以不依赖于编译器的方式进行。
Preferably, this should be done in a compiler-independent manner.
推荐答案
回答您的问题,关于如何加载64位值到XMM寄存器的低64位,同时将高64位的 _mm_loadl_epi64 (& x)
的源代码可以回答95 %的SSE / AVX上SO的问题。 Agner实现了这个(从文件vectori128.h)为多个编译器和64位和32位。请注意,MSVC 32位Agner的解决方案说这是低效的,但其他解决方案更糟糕。我想这是Mysticial的意思是没有一个好的方法来做。
In regards to _mm_set_epi64
I said once that looking at the source code of Agner Fog's Vector Class Library can answer 95% of the question on SSE/AVX on SO. Agner implemented this (from the file vectori128.h) for multiple compilers and for 64-bit and 32-bit. Note that the solution for MSVC 32-bit Agner says "this is inefficient, but other solutions are worse". I guess that's what Mysticial means by "There isn't a good way to do it.".
Vec2q(int64_t i0, int64_t i1) {
#if defined (_MSC_VER) && ! defined(__INTEL_COMPILER)
// MS compiler has no _mm_set_epi64x in 32 bit mode
#if defined(__x86_64__) // 64 bit mode
#if _MSC_VER < 1700
__m128i x0 = _mm_cvtsi64_si128(i0); // 64 bit load
__m128i x1 = _mm_cvtsi64_si128(i1); // 64 bit load
xmm = _mm_unpacklo_epi64(x0,x1); // combine
#else
xmm = _mm_set_epi64x(i1, i0);
#endif
#else // MS compiler in 32-bit mode
union {
int64_t q[2];
int32_t r[4];
} u;
u.q[0] = i0; u.q[1] = i1;
// this is inefficient, but other solutions are worse
xmm = _mm_setr_epi32(u.r[0], u.r[1], u.r[2], u.r[3]);
#endif // __x86_64__
#else // Other compilers
xmm = _mm_set_epi64x(i1, i0);
#endif
};
这篇关于从64位无符号整数初始化__m128类型的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!