bug-gnu-utils
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

pmovmskb source and target inversion


From: Alain Knaff
Subject: pmovmskb source and target inversion
Date: Mon, 23 Jul 2001 19:41:12 +0200

Gnu assembler 2.10.91 seems to inverse source and target registers for
the pmovmskb instruction (and possibly other MMX instructions as
well...).

For example
    pmovskb %mm0,%ecx will perform a pmovskb %mm1,%eax instead, and
vice-versa.

The following program shows the problem:

---------------------------------------------------------------------------
#include <stdio.h>


unsigned char mm0[] __attribute__ ((aligned(16))) = { 0x00, 0x00, 0x00, 0x00,
                                                      0x80, 0x80, 0x00, 0x00 };

unsigned char mm1[] __attribute__ ((aligned(16))) = { 0x08, 0x00, 0x00, 0x80,
                                                      0x80, 0x80, 0x00, 0x00 };


int main(int argc, char **argv) {
    unsigned int eax, ebx, ecx, edx;
    unsigned int esi, edi;

    asm volatile("      xorl %%eax,%%eax;\n"
                 "      xorl %%ebx,%%ebx;\n"
                 "      xorl %%ecx,%%ecx;\n"
                 "      xorl %%edx,%%edx;\n"
                 "      xorl %%esi,%%esi;\n"
                 "      xorl %%edi,%%edi;\n"
                 "      movq mm0,%%mm0;\n"
                 "      movq mm1,%%mm1;\n"
                 "      pmovmskb %%mm1,%%eax;\n" :
                 "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx),
                 "=S" (esi), "=D" (edi) );

    fprintf(stderr, "eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n",
            eax, ebx, ecx,edx, esi, edi);



    asm volatile("      xorl %%eax,%%eax;\n"
                 "      xorl %%ebx,%%ebx;\n"
                 "      xorl %%ecx,%%ecx;\n"
                 "      xorl %%edx,%%edx;\n"
                 "      xorl %%esi,%%esi;\n"
                 "      xorl %%edi,%%edi;\n"
                 "      movq mm0,%%mm0;\n"
                 "      movq mm1,%%mm1;\n"
                 "      pmovmskb %%mm0,%%ecx;\n" :
                 "=a" (eax), "=b" (ebx), "=c" (ecx), "=d" (edx),
                 "=S" (esi), "=D" (edi) );

    fprintf(stderr, "eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n",
            eax, ebx, ecx,edx, esi, edi);


    exit(0);
}
---------------------------------------------------------------------------

This prints 
eax=00000000 ebx=00000000 ecx=00000030 edx=00000000 esi=00000000 edi=00000000
eax=00000038 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000

rather than the expected:
eax=00000038 ebx=00000000 ecx=00000000 edx=00000000 esi=00000000 edi=00000000
eax=00000000 ebx=00000000 ecx=00000030 edx=00000000 esi=00000000 edi=00000000



And here is the cc -v output and assembler source:
---------------------------------------------------------------------------
> cc -v --save-temps mm-test.c
Reading specs from /usr/lib/gcc-lib/i486-suse-linux/2.95.3/specs
gcc version 2.95.3 20010315 (SuSE)
 /usr/lib/gcc-lib/i486-suse-linux/2.95.3/cpp0 -lang-c -v -D__GNUC__=2 
-D__GNUC_MINOR__=95 -D__ELF__ -Dunix -D__i386__ -Dlinux -D__ELF__ -D__unix__ 
-D__i386__ -D__linux__ -D__unix -D__linux -Asystem(posix) -Acpu(i386) 
-Amachine(i386) -Di386
-D__i386 -D__i386__ -Di486 -D__i486 -D__i486__ mm-test.c mm-test.i
GNU CPP version 2.95.3 20010315 (SuSE) (i386 Linux/ELF)
#include "..." search starts here:
#include <...> search starts here:
 /usr/local/include
 /usr/lib/gcc-lib/i486-suse-linux/2.95.3/include
 /usr/include
End of search list.
The following default directories have been omitted from the search path:
 /usr/include/g++
 /usr/lib/gcc-lib/i486-suse-linux/2.95.3/../../../../i486-suse-linux/include
End of omitted list.
 /usr/lib/gcc-lib/i486-suse-linux/2.95.3/cc1 mm-test.i -quiet -dumpbase 
mm-test.c -version -o mm-test.s
GNU C version 2.95.3 20010315 (SuSE) (i486-suse-linux) compiled by GNU C 
version 2.95.3 20010315 (SuSE).
 /usr/i486-suse-linux/bin/as -V -Qy -o mm-test.o mm-test.s
GNU assembler version 2.10.91 (i486-suse-linux) using BFD version 2.10.91.0.4
 /usr/lib/gcc-lib/i486-suse-linux/2.95.3/collect2 -m elf_i386 -dynamic-linker 
/lib/ld-linux.so.2 /usr/lib/crt1.o /usr/lib/crti.o 
/usr/lib/gcc-lib/i486-suse-linux/2.95.3/crtbegin.o 
-L/usr/lib/gcc-lib/i486-suse-linux/2.95.3 -L/usr/i486-suse-linux/lib mm-test.o 
-lgcc -lc -lgcc /usr/lib/gcc-lib/i486-suse-linux/2.95.3/crtend.o /usr/lib/crtn.o

---------------------------------------------------------------------------
        .file   "mm-test.c"
        .version        "01.01"
gcc2_compiled.:
.globl mm0
.data
        .align 16
        .type    mm0,@object
mm0:
.byte 0
.byte 0
.byte 0
.byte 0
.byte 128
.byte 128
.byte 0
.byte 0
        .size    mm0,8
.globl mm1
        .align 16
        .type    mm1,@object
mm1:
.byte 8
.byte 0
.byte 0
.byte 128
.byte 128
.byte 128
.byte 0
.byte 0
        .size    mm1,8
.section        .rodata
        .align 32
.LC0:
        .string "eax=%08x ebx=%08x ecx=%08x edx=%08x esi=%08x edi=%08x\n"
.text
        .align 16
.globl main
        .type    main,@function
main:
        pushl %ebp
        movl %esp,%ebp
        subl $44,%esp
        pushl %edi
        pushl %esi
        pushl %ebx
#APP
                xorl %eax,%eax;
        xorl %ebx,%ebx;
        xorl %ecx,%ecx;
        xorl %edx,%edx;
        xorl %esi,%esi;
        xorl %edi,%edi;
        movq mm0,%mm0;
        movq mm1,%mm1;
        pmovmskb %mm1,%eax;

#NO_APP
        movl %eax,-28(%ebp)
        movl -28(%ebp),%eax
        movl %eax,-4(%ebp)
        movl %ebx,%eax
        movl %eax,-8(%ebp)
        movl %ecx,%eax
        movl %eax,-12(%ebp)
        movl %edx,%eax
        movl %eax,-16(%ebp)
        movl %esi,%eax
        movl %eax,-20(%ebp)
        movl %edi,%eax
        movl %eax,-24(%ebp)
        movl -24(%ebp),%eax
        pushl %eax
        movl -20(%ebp),%eax
        pushl %eax
        movl -16(%ebp),%eax
        pushl %eax
        movl -12(%ebp),%eax
        pushl %eax
        movl -8(%ebp),%eax
        pushl %eax
        movl -4(%ebp),%eax
        pushl %eax
        pushl $.LC0
        movl stderr,%eax
        pushl %eax
        call fprintf
        addl $32,%esp
#APP
                xorl %eax,%eax;
        xorl %ebx,%ebx;
        xorl %ecx,%ecx;
        xorl %edx,%edx;
        xorl %esi,%esi;
        xorl %edi,%edi;
        movq mm0,%mm0;
        movq mm1,%mm1;
        pmovmskb %mm0,%ecx;

#NO_APP
        movl %eax,-32(%ebp)
        movl -32(%ebp),%eax
        movl %eax,-4(%ebp)
        movl %ebx,%eax
        movl %eax,-8(%ebp)
        movl %ecx,%eax
        movl %eax,-12(%ebp)
        movl %edx,%eax
        movl %eax,-16(%ebp)
        movl %esi,%eax
        movl %eax,-20(%ebp)
        movl %edi,%eax
        movl %eax,-24(%ebp)
        movl -24(%ebp),%eax
        pushl %eax
        movl -20(%ebp),%eax
        pushl %eax
        movl -16(%ebp),%eax
        pushl %eax
        movl -12(%ebp),%eax
        pushl %eax
        movl -8(%ebp),%eax
        pushl %eax
        movl -4(%ebp),%eax
        pushl %eax
        pushl $.LC0
        movl stderr,%eax
        pushl %eax
        call fprintf
        addl $32,%esp
        addl $-12,%esp
        pushl $0
        call exit
        addl $16,%esp
        .p2align 4,,7
.L2:
        leal -56(%ebp),%esp
        popl %ebx
        popl %esi
        popl %edi
        movl %ebp,%esp
        popl %ebp
        ret
.Lfe1:
        .size    main,.Lfe1-main
        .ident  "GCC: (GNU) 2.95.3 20010315 (SuSE)"

---------------------------------------------------------------------------

Thanks,

Alain



reply via email to

[Prev in Thread] Current Thread [Next in Thread]