FFmpeg の GENERAL_REGS 問題について再び
yuki さんから情報を頂きました.ありがとうございます.
http://d.hatena.ne.jp/eagletmt/20090315/1237114187#c1241296828
Lurker - Database message source pull failure
ふむ,これを読む限り-O2以上を渡せばよさそうです.
実際,
#include <stdio.h> #include <stdint.h> static void f(uint32_t *a, uint32_t *b) { asm volatile( "movd %4, %%mm0\n\t" "movd %5, %%mm1\n\t" "movd %6, %%mm2\n\t" "movd %7, %%mm3\n\t" "movd %%mm0, %0\n\t" "movd %%mm1, %1\n\t" "movd %%mm2, %2\n\t" "movd %%mm3, %3\n\t" : "=m"(b[0]), "=m"(b[1]), "=m"(b[2]), "=m"(b[3]) : "m"(a[0]), "m"(a[1]), "m"(a[2]), "m"(a[3]) ); } int main(void) { uint32_t a[4] = {1, 2, 3, 4}, b[4]; f(a, b); return 0; }
は,-O オプション無し,または -O0 だと
hoge.c: In function 'f': hoge.c:6: error: can't find a register in class 'GENERAL_REGS' while reloading 'asm' hoge.c:6: error: 'asm' operand has impossible constraints
とエラーが出るけど,-O1 とか -O2 を渡すと,正常にコンパイルされる.
インラインアセンブリといえども,前処理などは最適化オプションの影響を受けるのかぁ.
まぁ今思うと当然といえば当然か.
しかし,FFmpeg で普通に configure すると -O3 -fomit-frame-pointer がついてるんですよねぇ…
そのときのコマンドラインは
gcc -DHAVE_AV_CONFIG_H -I. -I"/Users/eagle/svn/ffmpeg" -D_ISOC99_SOURCE -D_POSIX_C_SOURCE=200112 -I/usr/local/include -I/opt/local include -std=c99 -D_FILE_OFFSET_BITS=64 -D_LARGEFILE_SOURCE -pipe -force_cpusubtype_ALL -Wno-sign-compare -fomit-frame-pointer march=core2 -g -Wdeclaration-after-statement -Wall -Wno-switch -Wdisabled-optimization -Wpointer-arith -Wredundant-decls -Wno-pointer-sign -Wcast-qual -Wwrite-strings -Wtype-limits -Wundef -O3 -fno-math-errno -fno-signed-zeros -c -o libavcodec/x86/dsputil_mmx.o libavcodec/x86/dsputil_mmx.c
こうなっている.
んで,エラーメッセージは
libavcodec/x86/h264dsp_mmx.c: In function 'h264_h_loop_filter_luma_mmx2': libavcodec/x86/dsputil_mmx.c:705: error: can't find a register in class 'GENERAL_REGS' while reloading 'asm' libavcodec/x86/dsputil_mmx.c:705: error: can't find a register in class 'GENERAL_REGS' while reloading 'asm' (snip)
なんですねぇ. @ gcc 4.3.3
というわけで,相変わらず ffmpeg-mmx-patch と libswscale-mmx-patch を使っております.