GCC4.8.3从内在函数生成无效的asm(操作数大小不匹配)

时间:2016-03-02 21:40:32

标签: c visual-c++ gcc assembly avx

我正在努力将MSVC应用程序迁移到Red-Hat Linux,并且遇到了一些使用的内在问题。我正在使用GCC 4.8.3以及以下命令行。

gcc -c file.c -o file.o -O2 -g -masm=intel -m32 -mavx -mavx2 -D_MMX_ -D_LARGEFILE64_SOURCE=1 -D_FILE_OFFSET_BITS=64 -D_GNU_SOURCE -pthread -fno-omit-frame-pointer -fno-tree-pre -fno-builtin-printf -Werror

伪代码是这样的

#include <immintrin.h>    // AVX/AVX2

void func_with_intrins(int x, int y, int h)
{
  short ddx;
  short ddy;
  int yh;
  ddx = xpos & 7;
  ddy = ypos & 7;
  ...

  for (yh = 0; yh < (h>>2); yh++)
  {
    if ((ddx + ddy) != 0)
    {
      __m128i ddxw = _mm_set1_epi16(ddx);
      ...
    }
    ...
  }
}

我已经读过_mm_set1_epi16内在函数可以扩展为vpbroadcastw,我已经通过查看生成的汇编文件确认了这一点。

vpbroadcastw    xmm0, XMMWORD PTR [ebp-216]

来自here

的定义
VPBROADCASTW xmm1, xmm2/m16
VPBROADCASTB/W/D/Q is supported in both 128-bit and 256-bit wide versions.

GCC给我的错误是

Error: operand size mismatch for `vpbroadcastw'

当我将优化级别从O2更改为O0时,程序集会有很大不同,并且不会使用vpbroadcastw指令。

由于我使用内在函数,我不知道该怎么做。将文件编译为O0不是一个选项。如果我将__m128i ddxw声明移到看似编译的循环之外,但我想我会更改底层功能。当移动到for循环之前时,vpbroadcastw代码需要两个xmm寄存器(堆栈变量是vmovdqa'd到xmm寄存器中)所以我认为gcc用完寄存器因此试图调用vpbroadcastw,第二个操作数是堆栈偏移量。

0 个答案:

没有答案
相关问题