【问题标题】:Load __m64 from a 64-bit integer type?从 64 位整数类型加载 __m64?
【发布时间】:2016-08-09 14:20:25
【问题描述】:

我正在将使用英特尔 SSE2 内部函数编写的例程移植到 Microsoft 32 位平台。它在 GCC、Clang 和 64 位 Windows 下运行良好。原始代码有效地执行了以下操作:

typedef unsigned __int64 word64;

// input is aligned on 16-byte boundary
void (const byte* input)
{
    const word64 m0 = ((const word64*)input)[ 0];
    const word64 m1 = ((const word64*)input)[ 8];
    ...

    __m128 t0 = _mm_set_epi64x(m0, m1);
}

微软在 32 位平台上不提供_mm_set_epi64x,所以我想使用_mm_set_epi64

现在的问题...首先,

__m64 m0, m1;
m0 = *(word64*)(input+0);

结果:

1>  error C2679: binary '=' : no operator found which takes a right-hand operand
of type 'word64' (or there is no acceptable conversion)
1>  c:\Program Files (x86)\Microsoft Visual Studio 10.0\VC\include\mmintrin.h(42):
could be '__m64 &__m64::operator =(const __m64 &)'
1>  while trying to match the argument list '(__m64, word64)'

其次,尝试回避word64 的潜在问题并直接使用unsigned __int64*

m0 = *(unsigned __int64*)(input+0);

结果相同:

1>  blake2.cpp(530): error C2679: binary '=' : no operator found which takes a right-hand
operand of type 'unsigned __int64' (or there is no acceptable conversion)

第三,我浏览了<mmintrin.h>,发现_m_from_int

m0 = _m_from_int(*(word64*)(input+0));

结果:

1>  blake2.cpp(529): warning C4244: 'argument' : conversion from 'word64'
to 'int', possible loss of data

目前我不确定还可以尝试什么。

如何从 64 位整数类型加载 __m64


下面是微软对__m64的声明,但我们应该把它当作不透明的:

typedef union __declspec(intrin_type) _CRT_ALIGN(8) __m64
{
    unsigned __int64    m64_u64;
    float               m64_f32[2];
    __int8              m64_i8[8];
    __int16             m64_i16[4];
    __int32             m64_i32[2];    
    __int64             m64_i64;
    unsigned __int8     m64_u8[8];
    unsigned __int16    m64_u16[4];
    unsigned __int32    m64_u32[2];
} __m64;

【问题讨论】:

标签: c windows visual-studio-2010 intrinsics sse2


【解决方案1】:

首先我注意到您的输入是一个字节数组。从字节数组转换为多字节二进制文件(如 int64)时,您可能需要考虑字节顺序。出于这个问题的目的,我将忽略这个问题,但如果你得到“看起来有问题”的东西,那就需要考虑了。

在第一个错误中,编译器在将解引用指针转换为 word64(无符号 __int64)时遇到问题。我没有准备好访问标题,但我怀疑这可能与“const”有关。您想要一个复制运算符,但我相信您正在获得分配运算符。您的第二个编译器错误 (m0 = (unsigned __int64)(input+0);)

您的第三个错误似乎是由 _m_to_int 期望一个有符号的 int64 并得到一个无符号的 int64 引起的。

我想知道是不是这样的:

const word64 *m0 = ((const word64*)input)[ 0];

const word64 m0 = &((const word64*)input);

可以吗?

【讨论】:

  • 感谢 Dweeberly。如果有兴趣,该文件可在blake2.cpp 获得。感兴趣的函数是BLAKE2_SSE2_Compress64。 BLAKE2 是小端。在某些地方必须小心,但不是这个区域,因为它旨在通过使用本机字节顺序在 IBM 兼容机上快速运行。
猜你喜欢
  • 1970-01-01
  • 2012-10-18
  • 2014-06-22
  • 2019-03-02
  • 1970-01-01
  • 2010-11-02
  • 1970-01-01
  • 2019-07-20
  • 1970-01-01
相关资源
最近更新 更多