Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/css/32.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ _MM_TRANSPOSE4_PS导致GCC中的编译器错误?_C++_Visual C++_Gcc_Sse_Intrinsics - Fatal编程技术网

C++ _MM_TRANSPOSE4_PS导致GCC中的编译器错误?

C++ _MM_TRANSPOSE4_PS导致GCC中的编译器错误?,c++,visual-c++,gcc,sse,intrinsics,C++,Visual C++,Gcc,Sse,Intrinsics,我第一次用GCC而不是MSVC编译我的数学库,并经历了所有的小错误,我发现了一个根本没有意义的错误: 第284行:错误:赋值的左操作数需要左值 284线有什么?这: _MM_TRANSPOSE4_PS(r,u,t,_MM_setr_PS(0.0f,0.0f,0.0f,1.0f)) (r、u和t都是\uu m128的实例) 熟悉使用xmmintrin.h的人会知道\u MM\u TRANSPOSE4\u PS实际上不是一个函数,而是一个宏,它可以扩展为: /* Transpose the 4x4

我第一次用GCC而不是MSVC编译我的数学库,并经历了所有的小错误,我发现了一个根本没有意义的错误:

第284行:错误:赋值的左操作数需要左值

284线有什么?这:

_MM_TRANSPOSE4_PS(r,u,t,_MM_setr_PS(0.0f,0.0f,0.0f,1.0f))

(r、u和t都是
\uu m128
的实例)

熟悉使用
xmmintrin.h
的人会知道
\u MM\u TRANSPOSE4\u PS
实际上不是一个函数,而是一个宏,它可以扩展为:

/* Transpose the 4x4 matrix composed of row[0-3].  */
#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3)           \
do {                                    \
  __v4sf __r0 = (row0), __r1 = (row1), __r2 = (row2), __r3 = (row3);    \
  __v4sf __t0 = __builtin_ia32_unpcklps (__r0, __r1);           \
  __v4sf __t1 = __builtin_ia32_unpcklps (__r2, __r3);           \
  __v4sf __t2 = __builtin_ia32_unpckhps (__r0, __r1);           \
  __v4sf __t3 = __builtin_ia32_unpckhps (__r2, __r3);           \
  (row0) = __builtin_ia32_movlhps (__t0, __t1);             \
  (row1) = __builtin_ia32_movhlps (__t1, __t0);             \
  (row2) = __builtin_ia32_movlhps (__t2, __t3);             \
  (row3) = __builtin_ia32_movhlps (__t3, __t2);             \
} while (0)
所以。。。什么导致了我的编译器错误?据我所知,这里我没有重新定义任何东西。当我使用MSVC时,这段代码编译并运行得非常好。

您需要更改:

_MM_TRANSPOSE4_PS(r, u, t, _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f));
致:


因为这是一个就地转置,4个输入向量也用于输出。

MSVC使用自己的定义:

#define _MM_TRANSPOSE4_PS(row0, row1, row2, row3) {                 \
            __m128 tmp3, tmp2, tmp1, tmp0;                          \
                                                                    \
            tmp0   = _mm_shuffle_ps((row0), (row1), 0x44);          \
            tmp2   = _mm_shuffle_ps((row0), (row1), 0xEE);          \
            tmp1   = _mm_shuffle_ps((row2), (row3), 0x44);          \
            tmp3   = _mm_shuffle_ps((row2), (row3), 0xEE);          \
                                                                    \
            (row0) = _mm_shuffle_ps(tmp0, tmp1, 0x88);              \
            (row1) = _mm_shuffle_ps(tmp0, tmp1, 0xDD);              \
            (row2) = _mm_shuffle_ps(tmp2, tmp3, 0x88);              \
            (row3) = _mm_shuffle_ps(tmp2, tmp3, 0xDD);              \
        }
最后一行正在转换为
\u mm\u setr\u ps(0.0f、0.0f、0.0f、1.0f)=\u mm\u shuffle\u ps(tmp2、tmp3、0XDD)
在MSVC中编译得很好,但在GCC中由于左值错误而失败。我不知道MSVC为什么允许这样做

我在MSVC2013中查看了这段代码的汇编输出

#include <immintrin.h>
#include <stdio.h>
int main() 
{

    __m128 rows[4];
    //rows[0] = _mm_setr_ps( 1, 2, 3, 4);
    //rows[1] = _mm_setr_ps( 5, 6, 7, 8);
    rows[2] = _mm_setr_ps( 9,10,11,12);
    rows[3] = _mm_setr_ps(13,14,15,16);

    //_MM_TRANSPOSE4_PS(rows[0],rows[1],rows[2],rows[3]);
    //_MM_TRANSPOSE4_PS(rows[0],rows[1],rows[2],_mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f));
    rows[2] = _mm_shuffle_ps(rows[2], rows[3], 0x88);
    _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f) = _mm_shuffle_ps(rows[2],rows[3], 0XDD);
}

显然,<代码> *MMXSETrpIPS(0.0F,0.0F,0.0F,1.0F)< /C> >不扩展到LVal.这是C还是C++代码?代码段是C++。我在问题中添加了VisualC++和内联标记。这确实是MSVC的问题,而不是GCC的问题。谢谢,这解决了它。为什么它让我在MSVC中这样做,而不是在GCC中?两个编译器的
\u MM\u TRANSPOSE4\u PS
的定义是否相同?它直接使用了内部函数。GCC将
\u mm\u unpaclo\u ps
定义为一个内联函数,该函数调用
\u内置\u ia32\u unpacps
。如果在这个宏中使用
\u mm\u unplo\u ps
,你的代码也会因为同样的原因失败。@RossRidge,是的,我现在明白了。问题在于MSVC。它编译并运行
\u mm\u setr\u ps(0.0f,0.0f,0.0f,1.0f)=\u mm\u shuffle\u ps(tmp2,tmp3,0XDD)很好。@PaulR,我的第一个答案真的很难听,我很惊讶我没有被否决。但无论如何,我用MSVC的汇编输出更新了我的答案。我不确定它在做什么,但它显然没有将结果存储在行中。我仍然不清楚如何将
row3
参数设置为
\u mm\u setr\u ps(…)
可以工作,因为它是在宏的最后一行分配的?@PaulR,好的观点。但是即使它给出了错误的结果,它仍然应该编译(
\u mm\u setr\u ps(0.0f,0.0f,0.0f,1.0f)=\u mm\u shuffle\u ps(tmp2,tmp3,0XDD)
)。但我仍然想知道为什么GCC使用映射到内部函数的内置函数,而不是直接映射到内部函数。我想一个原因是为了防止这种错误的发生?不-我认为gcc完全正确地避免了
错误:赋值的左操作数需要左值(…)
不是左值,尝试将其赋值真的是一个错误-我不知道这是如何通过MSVC的-也许MS定义
\u mm\u setr\u ps
的方式有些可笑?@PaulR,又对了。我对他的考虑不够仔细。无论如何,这就是线索
\u mm\u setr\u ps(0.0f,0.0f,0.0f,1.0f)=\u mm\u shuffle\u ps(tmp2,tmp3,0XDD)
在MSVC中编译得很好,但在GCC中给出了
左值
错误。我明天再调查这件事。我不知道我为什么再关心MSVC了。。。
#include <immintrin.h>
#include <stdio.h>
int main() 
{

    __m128 rows[4];
    //rows[0] = _mm_setr_ps( 1, 2, 3, 4);
    //rows[1] = _mm_setr_ps( 5, 6, 7, 8);
    rows[2] = _mm_setr_ps( 9,10,11,12);
    rows[3] = _mm_setr_ps(13,14,15,16);

    //_MM_TRANSPOSE4_PS(rows[0],rows[1],rows[2],rows[3]);
    //_MM_TRANSPOSE4_PS(rows[0],rows[1],rows[2],_mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f));
    rows[2] = _mm_shuffle_ps(rows[2], rows[3], 0x88);
    _mm_setr_ps(0.0f, 0.0f, 0.0f, 1.0f) = _mm_shuffle_ps(rows[2],rows[3], 0XDD);
}
; Line 14
    mov eax, 16
    imul    rax, 3
    mov ecx, 16
    imul    rcx, 2
    movups  xmm0, XMMWORD PTR rows$[rsp+rcx]
    shufps  xmm0, XMMWORD PTR rows$[rsp+rax], 136   ; 00000088H
    movaps  XMMWORD PTR $T6[rsp], xmm0
    mov eax, 16
    imul    rax, 2
    movaps  xmm0, XMMWORD PTR $T6[rsp]
    movups  XMMWORD PTR rows$[rsp+rax], xmm0
; Line 15
    mov eax, 16
    imul    rax, 3
    mov ecx, 16
    imul    rcx, 2
    movups  xmm0, XMMWORD PTR rows$[rsp+rcx]
    shufps  xmm0, XMMWORD PTR rows$[rsp+rax], 221   ; 000000ddH
    movaps  XMMWORD PTR $T8[rsp], xmm0
    movaps  xmm0, XMMWORD PTR __xmm@3f800000000000000000000000000000
    movaps  XMMWORD PTR $T7[rsp], xmm0
    movaps  xmm0, XMMWORD PTR $T8[rsp]
    movaps  XMMWORD PTR $T7[rsp], xmm0