A bug in IA32 assembler
H . J . Lu
hjl@lucon.org
Thu Jun 28 18:12:00 GMT 2001
On Fri, Jun 29, 2001 at 10:21:20AM +0930, Alan Modra wrote:
> > > >
> > > > Which one is valid,
> > > >
> > > > movaps (A.3),%xmm0
> > > >
> > > > or
> > > > movaps ($A.3),%xmm0
> > >
> > > Both, I suppose, although the second one is trickery to get a
> >
> > Are they the same? FYI, gcc seems to generate both from asm statements.
>
> No. They reference different symbols.
Compile the code with gcc 2.96 from RedHat 7.1,
asm("movaps (%0),%%xmm0" //SSE
:
:"g"(A));
generates
movaps ($A.0),%xmm0
But
asm("movaps %%xmm0,(%0)":"=g"(C)); //SSE
gets
movaps %xmm0,(C.2)
>
> > > '$' into a label.
> > >
> > > movaps A.3,%xmm0
> > >
> > > is really what you want; Your added parentheses just act as they
> > > normally do in arithmetic expressions.
> >
> > Right now, gas treats $A.3 as a label in
> >
> > movaps ($A.3),%xmm0
> >
> > That is the relocation is against `$A.3'. Also it doesn't allow
> >
> > movaps $A.3,%xmm0
> >
> > Do you have a fix for it?
>
> I don't understand what you want a "fix" for. "$A.3" in your last
> example is an immediate with value of the address of "A.3". movaps
> doesn't accept immediates, only xmm registers or memory.
>
> It's not at all normal to have `$' in labels on x86, as `$' is the
> immediate prefix. Do you think your trickery with `($A.3)' should
> not be allowed?
Since
movaps (A),%xmm0
generates the same binary as
movaps A,%xmm0
shouldn't we treat
movaps ($A.3),%xmm0
the same as
movaps $A.3,%xmm0
H.J.
------
/* test program for SSE by kaz @ kobe1995.net
% cc -g bug.c && ./a.out
But it fails. So,
% cc -g -S bug.c
And change bug.s to avoid bug of gcc (may be):
#APP
- movaps ($A.15),%xmm0
- movaps ($B.16),%xmm1
+ movaps A.15,%xmm0
+ movaps B.16,%xmm1
#NO_APP
% c++ loop.s && ./a.out
*/
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdlib.h>
#include <limits.h>
main(){
static float __attribute__((aligned(16)))
A[4]={1.,1.,1.,1.},
B[4]={0.,1.,2.,3.},
C[4];
int i;
printf("float A=(");
for(i=0;i<4;i++) printf("%f,",A[i]);
printf("\b)\n");
printf("float B=(");
for(i=0;i<4;i++) printf("%f,",B[i]);
printf("\b)\n");
asm("movaps (%0),%%xmm0" //SSE
:
:"g"(A));
asm("movaps (%0),%%xmm1" //SSE
:
:"g"(B));
asm("addps %xmm1,%xmm0"); //SSE
// asm("mulps %xmm1,%xmm0"); //SSE
asm("movaps %%xmm0,(%0)":"=g"(C)); //SSE
printf("float C=(");
for(i=0;i<4;i++) printf("%f,",C[i]);
printf("\b)\n");
}
More information about the Binutils
mailing list