[Top][All Lists]
[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
[Prev in Thread] |
Current Thread |
[Next in Thread] |
- pmovmskb source and target inversion,
Alain Knaff <=