[FFmpeg-devel] [PATCH 1/2] Fix miscompilation for i586.
Mikulas Patocka
mikulas at artax.karlin.mff.cuni.cz
Sun Sep 14 01:01:45 CEST 2014
> > Hi
> >
> > Here I'm sending two patches to fix portability for 586-class machines
> > (Pentium, K6, etc.)
> >
> >
> > If the CPU is generic, 386, 486 or pentium, we must not use cmov in inline
> > assembler.
> >
> > Note that some Linux distributions are compiled for i686, and for them it is
> > possible to use cmov in the assembler (because gcc uses it anyway). To test for
> > this case, we test for defined(__i686__) || defined(__athlon__) ||
> > defined(__SSE__) (these macros are driven by -march flag to gcc) and use cmov if
> > one of these conditions is true.
> >
> > ---
> > configure | 4 ++++
> > libavcodec/x86/mathops.h | 2 +-
> > 2 files changed, 5 insertions(+), 1 deletion(-)
> >
> > Index: ffmpeg/configure
> > ===================================================================
> > --- ffmpeg.orig/configure 2014-09-12 21:46:25.710512294 +0200
> > +++ ffmpeg/configure 2014-09-12 21:46:32.099587711 +0200
> > @@ -3840,8 +3840,12 @@ elif enabled sparc; then
> > elif enabled x86; then
> >
> > case $cpu in
> > + generic)
> > + disable i686
> > + ;;
> i686 extensions were specifically enabled some time ago by default,
> since we live in a modern world.
> If you're building for a older system, its your responsibility to pass
> the appropriate option.
>
> > i[345]86|pentium)
> > cpuflags="-march=$cpu"
> > + disable i686
> > disable mmx
> > ;;
> > # targets that do NOT support nopl and conditional mov (cmov)
> > Index: ffmpeg/libavcodec/x86/mathops.h
> > ===================================================================
> > --- ffmpeg.orig/libavcodec/x86/mathops.h 2014-09-12 21:46:05.823390224 +0200
> > +++ ffmpeg/libavcodec/x86/mathops.h 2014-09-12 21:46:32.116251966 +0200
> > @@ -69,7 +69,7 @@ static av_always_inline av_const int64_t
> >
> > #endif /* ARCH_X86_32 */
> >
> > -#if HAVE_I686
> > +#if HAVE_I686 || defined(__i686__) || defined(__athlon__) || defined(__SSE__)
> > /* median of 3 */
> > #define mid_pred mid_pred
> > static inline av_const int mid_pred(int a, int b, int c)
>
> I don't like this part, configure should control if the code is used,
> and if the i686 extensions are not enabled in configure, then they
> should not be built here.
In my opinion you could remove HAVE_I686 and disable/enable i686 at all.
The user sets CFLAGS="-march=xxx" variable when running ./configure and it
selects the instruction set that is being generated.
In the program, you can easily determine what -march was passed to the
compiler and react to it - if one of __i686__, __athlon__, __SSE__ is
defined, you can use cmov, because the compiler is already generating
cmov.
The problem is this: Debian or Slackware is compiled with -march=i586. So
you don't want cmov to be generated when building binary for them. Fedora
is compiled with -march=i686, so you can use cmov. But your configure
script doesn't know if it is building a binary for Debian or Fedora, so it
can't magically detect if generating cmov is appropriate or not. If you
make decision based on -march, it will be right on all distributions.
Mikulas
More information about the ffmpeg-devel
mailing list