c++ - 错误 : ‘asm’ operand has impossible constraints when using gcc 32bit

标签 c++ gcc assembly webrtc

我正在尝试在 32 位 centos6 上编译 webrtc 并出现以下错误。但这在 64 位 centos 上运行良好。有人可以帮助我吗?

row_gcc.cc:3574:4: error: ‘asm’ operand has impossible constraints

编译命令:

CXX obj/chromium/src/third_party/libyuv/source/libyuv.row_gcc.o
FAILED: obj/chromium/src/third_party/libyuv/source/libyuv.row_gcc.o 
c++ -MMD -MF obj/chromium/src/third_party/libyuv/source/libyuv.row_gcc.o.d 
-DV8_DEPRECATION_WARNINGS -D_FILE_OFFSET_BITS=64 -DCHROMIUM_BUILD 
-DUI_COMPOSITOR_IMAGE_TRANSPORT -DUSE_AURA=1 -DUSE_PANGO=1 -DUSE_CAIRO=1 
-DUSE_DEFAULT_RENDER_THEME=1 -DUSE_LIBJPEG_TURBO=1 -DUSE_X11=1 
-DUSE_CLIPBOARD_AURAX11=1 -DENABLE_WEBRTC=1 -DENABLE_MEDIA_ROUTER=1 
-DENABLE_PEPPER_CDMS -DENABLE_NOTIFICATIONS -DENABLE_TOPCHROME_MD=1 
-DUSE_UDEV -DFIELDTRIAL_TESTING_ENABLED -DENABLE_TASK_MANAGER=1 
-DENABLE_EXTENSIONS=1 -DENABLE_PDF=1 -DENABLE_PLUGINS=1 
-DENABLE_SESSION_SERVICE=1 -DENABLE_THEMES=1 -DENABLE_PRINTING=1 
-DENABLE_BASIC_PRINTING=1 -DENABLE_PRINT_PREVIEW=1 -DENABLE_SPELLCHECK=1 
-DENABLE_CAPTIVE_PORTAL_DETECTION=1 -DENABLE_APP_LIST=1 
-DENABLE_SETTINGS_APP=1 -DENABLE_SUPERVISED_USERS=1 -DENABLE_MDNS=1 
-DENABLE_SERVICE_DISCOVERY=1 -DV8_USE_EXTERNAL_STARTUP_DATA 
-DFULL_SAFE_BROWSING -DSAFE_BROWSING_CSD -DSAFE_BROWSING_DB_LOCAL 
-DHAVE_JPEG -DUSE_LIBPCI=1 -DUSE_GLIB=1 -DUSE_NSS_CERTS=1 
-D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS 
-DDYNAMIC_ANNOTATIONS_ENABLED=1 -DWTF_USE_DYNAMIC_ANNOTATIONS=1 
-D_DEBUG -Igen 
-I../../chromium/src/third_party/libyuv/include 
-I../../chromium/src/third_party/libyuv 
-I../../chromium/src/third_party/libjpeg_turbo -fstack-protector 
--param=ssp-buffer-size=4  -pthread -fno-strict-aliasing -Wall -Wno-extra 
-Wno-unused-parameter -Wno-missing-field-initializers -fvisibility=hidden 
-pipe -fPIC 
-B/home/test/webrtc-checkout/src/third_party/binutils/Linux_ia32/Release/bin 
-Wno-unused-local-typedefs -msse2 -mfpmath=sse -mmmx -m32 -O0 -g 
-funwind-tables -fno-exceptions -fno-rtti -fno-threadsafe-statics 
-fvisibility-inlines-hidden 
-std=gnu++11 -Wno-narrowing  
-c ../../chromium/src/third_party/libyuv/source/row_gcc.cc 
-o  obj/chromium/src/third_party/libyuv/source/libyuv.row_gcc.o
../../chromium/src/third_party/libyuv/source/row_gcc.cc: 
In function ‘void libyuv::BlendPlaneRow_SSSE3(const uint8*, 
const uint8*, const uint8*, uint8*, int)’:
../../chromium/src/third_party/libyuv/source/row_gcc.cc:3574:4: 
error: ‘asm’ operand has impossible constraints

海湾合作委员会版本:4.8.5

作为版本:GNU assembler (GNU Binutils) 2.26.20160125

third_party/binutils/Linux_ia32/Release/bin/as --version
GNU assembler (GNU Binutils) 2.26.20160125
Copyright (C) 2015 Free Software Foundation, Inc.
This program is free software; you may redistribute it under the terms of
the GNU General Public License version 3 or later.
This program has absolutely no warranty.
This assembler was configured for a target of `i686-pc-linux-gnu'.

chromium/src/third_party/libyuv/source/row_gcc.cc中的代码:

void BlendPlaneRow_SSSE3(const uint8* src0, const uint8* src1,
                     const uint8* alpha, uint8* dst, int width) {
asm volatile (
"pcmpeqb    %%xmm5,%%xmm5                  \n"
"psllw      $0x8,%%xmm5                    \n"
"mov        $0x80808080,%%eax              \n"
"movd       %%eax,%%xmm6                   \n"
"pshufd     $0x0,%%xmm6,%%xmm6             \n"
"mov        $0x807f807f,%%eax              \n"
"movd       %%eax,%%xmm7                   \n"
"pshufd     $0x0,%%xmm7,%%xmm7             \n"
"sub        %2,%0                          \n"
"sub        %2,%1                          \n"
"sub        %2,%3                          \n"

// 8 pixel loop.
LABELALIGN
"1:                                          \n"
"movq       (%2),%%xmm0                    \n"
"punpcklbw  %%xmm0,%%xmm0                  \n"
"pxor       %%xmm5,%%xmm0                  \n"
"movq       (%0,%2,1),%%xmm1               \n"
"movq       (%1,%2,1),%%xmm2               \n"
"punpcklbw  %%xmm2,%%xmm1                  \n"
"psubb      %%xmm6,%%xmm1                  \n"
"pmaddubsw  %%xmm1,%%xmm0                  \n"
"paddw      %%xmm7,%%xmm0                  \n"
"psrlw      $0x8,%%xmm0                    \n"
"packuswb   %%xmm0,%%xmm0                  \n"
"movq       %%xmm0,(%3,%2,1)               \n"
"lea        0x8(%2),%2                     \n"
"sub        $0x8,%4                        \n"
"jg        1b                              \n"
: "+r"(src0),       // %0
"+r"(src1),       // %1
"+r"(alpha),      // %2
"+r"(dst),        // %3
"+r"(width)       // %4
:: "memory", "cc", "eax", "xmm0", "xmm1", "xmm2", "xmm5", "xmm6", "xmm7"
);

最佳答案

就像 David Wohlfred 所说的那样,问题是您的寄存器用完了。有 8 个通用寄存器,其中之一是 ESP,堆栈指针,永远不能用于满足约束。由于您正在编译的选项,另外两个寄存器 EBP 和 EBX 也不能用于满足约束。由于您在没有优化的情况下进行编译,因此 EBP 寄存器保留用于帧指针,并且由于您使用的是 -fPIC 标志,因此保留 EBX 寄存器以访问 GOT(全局对象表) .

所以留下五个寄存器可以用来满足寄存器约束,EAX、ECX、EDX、ESI和EDI。但是,您的 asm 语句破坏了 EAX,因此无法使用,只留下四个寄存器。 asm 语句有五个具有寄存器约束的操作数,这意味着它需要五个独立的寄存器,但只有四个可供编译器使用。所以约束是不可能满足的。

一个简单的解决方案是通过在 asm 语句中删除对 EAX 的使用来释放寄存器。该寄存器用于将两个不同的常量值加载到两个不同的 XMM 寄存器中。相反,可以直接从内存中加载常量。例如:

void BlendPlaneRow_SSSE3(const uint8* src0, const uint8* src1,
                     const uint8* alpha, uint8* dst, int width) {
        static unsigned const __attribute__((aligned(4))) xmm6[4] = {
                 0x80808080, 0x80808080, 0x80808080, 0x80808080
        };
        static unsigned const __attribute__((aligned(4))) xmm7[4] = {
                 0x807f807f, 0x807f807f, 0x807f807f, 0x807f807f
        };

asm volatile (
"pcmpeqb    %%xmm5,%%xmm5                  \n"
"psllw      $0x8,%%xmm5                    \n"
"movaps     %5,%%xmm6                      \n"
"movaps     %6,%%xmm7                      \n"
"sub        %2,%0                          \n"
"sub        %2,%1                          \n"
"sub        %2,%3                          \n"

// 8 pixel loop.
LABELALIGN
"1:                                          \n"
"movq       (%2),%%xmm0                    \n"
"punpcklbw  %%xmm0,%%xmm0                  \n"
"pxor       %%xmm5,%%xmm0                  \n"
"movq       (%0,%2,1),%%xmm1               \n"
"movq       (%1,%2,1),%%xmm2               \n"
"punpcklbw  %%xmm2,%%xmm1                  \n"
"psubb      %%xmm6,%%xmm1                  \n"
"pmaddubsw  %%xmm1,%%xmm0                  \n"
"paddw      %%xmm7,%%xmm0                  \n"
"psrlw      $0x8,%%xmm0                    \n"
"packuswb   %%xmm0,%%xmm0                  \n"
"movq       %%xmm0,(%3,%2,1)               \n"
"lea        0x8(%2),%2                     \n"
"sub        $0x8,%4                        \n"
"jg        1b                              \n"
: "+r"(src0),       // %0
"+r"(src1),       // %1
"+r"(alpha),      // %2
"+r"(dst),        // %3
"+r"(width)       // %4
: "m" (xmm6),
"m" (xmm7)
: "memory", "cc", "xmm0", "xmm1", "xmm2", "xmm5", "xmm6", "xmm7"
);
}

更好的解决方案是重写它以使用内部函数并让编译器完成所有寄存器分配。

关于c++ - 错误 : ‘asm’ operand has impossible constraints when using gcc 32bit,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/37494203/

相关文章:

c++ - 指向数组声明的指针

c - C中不同的执行和输入字符集

c++ - 我可以使用 cmpxchg16b 以原子方式将指针复制到指针和 int,同时递增 int(原子引用计数)吗?

assembly - 手动计算物理地址(IDTR 寄存器)

assembly - ASM Call指令导致堆栈溢出?

c++ - 数组类型在函数调用中用作引用类型参数

c++ - 宏参数列表中的指针

c - 如何创建宏字符串

c++ - gcc 4.5.1 vs VC2010 模板部分特化 : which is C++0x conformant?

c# - 如何获取硬盘传输模式?