错误:使用gcc 32位时,"asm"操作数具有不可能的约束
error: ‘asm’ operand has impossible constraints when using gcc 32bit
我试图在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
gcc版本:4.8.5
as版本:GNU汇编程序(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'.
chrome/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# HashSet VS C++ std::unordered_set 使用自定义类键。C++慢...不可能。如何实现 C# 的速度?
- 为什么在C++不可能递增或进行数学运算,例如在声明为数组的变量上乘法
- fopen 与常量字符 * 从 QString 是不可能的
- 矢量返回常量引用,不可能向下转换
- 分配取消引用的字符指针真的不可能吗?
- C#类过程 - 控制C 应用程序,不可能读取输出
- 可能是不可能的模板参数规范/推论
- 易失性结构 = 结构不可能,为什么?
- 矢量超出范围,将值分配给空矢量>不可能?
- 为什么不可能实例化原子对
- 一个倒梯形,但如果输入高度对于宽度来说太大,那么它应该报告,不可能("不可能的形状"是什么)
- W10上不可能使用十字架编译的libpng16-16.dll执行
- 如果明确给出多维数组,为什么不可能char [] [] [] = {..},{..}}
- “并非所有控制路径都返回一个值./&quot“控制可能达到非空隙功能的末端”.验证时循环时
- 为什么我的自定义界面总是返回不可能的0x80040213/VFW_E_NO_CLOCK
- 从张量的读取设备不可能的方法
- 多态性抽象语法树(递归下降解析器):不可能
- IDXGISwapChain::CheckInterfaceSupport 返回一个不可能的结果
- C++为什么不可能将这两个操作合并在一行中?
- 指针将指针的指针等同于指针指向指针.不可能