[FFmpeg-devel] r9017 breaks WMA decoding on Intel Macs

Trent Piepho xyzzy
Thu May 31 13:58:24 CEST 2007


On Thu, 31 May 2007, Matthieu CASTET wrote:
> Trent Piepho <xyzzy <at> speakeasy.org> writes:
>
> > I wouldn't consider it a workaround, but a better way to write the code to
> > begin with.
> >
> > The use of the asm("n+%0" :  "m"(foo)) syntax has a bug.  The asm block has an
> > undeclared input or output.  The fact that the existing code works is simply
> > luck that gcc's optimizer isn't able to do something to break it.
> >
> > Consider something like this:
> > int main(void)
> > {
> >     int x[2] = {1, 1};
> >     asm("movl $42, %0 ; movl $42, 4+%0" : "=m"(x[0]));
> >     printf("%d\n", x[1]);
> > }
> >

> You can declare the memory you are accessing with something like :
>
> int main(void)
> {
>     int x[2] = {1, 1};
>     struct { int a[2]; } *p = (void *)x;
>     asm("movl $42, %0 \n\t movl $42, 4+%0" :
>             "+m" (*p)
>        );
>     printf("%d\n", x[1]);
> }
>
>
> Matthieu
>
> PS : gcc manual [1] give a (ugly) syntax to make the struct cast in asm
> input/ouput declaration, but I didn't manage to make it work for output.

This worked for me:
asm("movl $42, %0 ; movl $42, 4+%0" : "=m"(*(struct{int a[2];}*)x));

Ugly, but you could always make a macro out of it.
#define MEMCLOBBER(x,len) (*(struct{char a[len];}*)(x))
or specify the length in elements instead of bytes:
#define MEMCLOBBER(x,len) (*(struct{char a[sizeof(*(x))*(len)];}*)(x))

asm("movl $42, %0 ; movl $42, 4+%0" : "=m"(MEMCLOBBBER(x, 2)));

But in this case, it seems like the obvious way to write this is:

asm("movl $42, %0 ; movl $42, %1" : "=m"(x[0]), "=m"(x[1]));

If there is some small fixed number of operands, you can just list them all.
This avoids the problem with the "4+%0" syntax, which is invalid according to
the gas docs.  Current gas just happens to print a warning instead of an error
and produce the desired output.

> [1]
> If you know how large the accessed memory is, you can add it as input or output
> but if this is not known, you should add `memory'. As an example, if you access

The problem with adding "memory" to the clobber list is that it really kills
optimization.  All registers must be re-loaded after the asm block and so on.
It's good to avoid it when possible.




More information about the ffmpeg-devel mailing list