m68k assembly operand mismatch in asm statement using "=d"
David D. Kilzer
ddkilzer@earthlink.net
Mon Mar 15 21:01:00 GMT 1999
Hi,
I believe I've found a bug in egcs-2.91.60 19981201 (egcs-1.1.1
release).
I'm running MkLinux on a Power Mac 8500/150 (equivalent to LinuxPPC-R4).
The egcs compiler is an m68k-linux cross-compiler (with cross-binutils)
that I built myself. RPMs of the cross-compiler, cross-binutils and
m68k-gcclib are available. (More details available if needed.)
I was building a stock Linux-2.0.36 kernel + m68k patches + mac-m68k
patches for the Mac port of Linux/m68k. The code in question is part
of the FPU emulator. (More details available if needed.)
I have narrowed the test case down to less than 50 lines of C source
code which generates less than 50 lines of m68k assembly.
The following instruction causes the problem:
bfffo %a1{#0,#32},%d0
The C source file explicitly requests data registers, but an address
register is used in one case out of four.
The following files (named after the m68k instruction in the asm{}
statement) have been included in-line:
bfffo.script -- Output from egcs -v --save-temps ... command
bfffo.c -- C source file
bfffo.i -- preprocessed source
bfffo.s -- m68k assembly
Any help would be appreciated. Thanks!
Dave
------- Included file bfffo.script
[root@cartman math-emu]# /usr/local/m68k-linux/bin/gcc -v --save-temps -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -fno-strength-reduce -pipe -c -o bfffo.o bfffo.c
gcc: Warning: -pipe ignored since -save-temps specified
Reading specs from /usr/m68k-linux/lib/gcc-lib/m68k-linux/egcs-2.91.60/specs
gcc version egcs-2.91.60 19981201 (egcs-1.1.1 release)
/usr/m68k-linux/lib/gcc-lib/m68k-linux/egcs-2.91.60/cpp -lang-c -v -undef -D__GNUC__=2 -D__GNUC_MINOR__=91 -D__ELF__ -Dunix -Dmc68000 -Dmc68020 -Dlinux -D__ELF__ -D__unix__ -D__mc68000__ -D__mc68020__ -D__linux__ -D__unix -D__mc68000 -D__mc68020 -D__linux -Asystem(unix) -Asystem(posix) -Acpu(m68k) -Amachine(m68k) -D__OPTIMIZE__ -Wall -Wstrict-prototypes -D__HAVE_68881__ bfffo.c bfffo.i
GNU CPP version egcs-2.91.60 19981201 (egcs-1.1.1 release) (68k GNU/Linux with ELF)
#include "..." search starts here:
#include <...> search starts here:
/usr/m68k-linux/lib/gcc-lib/m68k-linux/egcs-2.91.60/include
End of search list.
/usr/m68k-linux/lib/gcc-lib/m68k-linux/egcs-2.91.60/cc1 bfffo.i -quiet -dumpbase bfffo.c -O2 -Wall -Wstrict-prototypes -version -fomit-frame-pointer -fno-strength-reduce -o bfffo.s
GNU C version egcs-2.91.60 19981201 (egcs-1.1.1 release) (m68k-linux) compiled by GNU C version egcs-2.91.60 19981201 (egcs-1.1.1 release).
m68k-linux-as -V -Qy -o bfffo.o bfffo.s
GNU assembler version 2.9.1 (m68k-linux), using BFD version 2.9.1.0.4
bfffo.s: Assembler messages:
bfffo.s:33: Error: operands mismatch -- statement `bfffo %a1{#0,#32},%d0' ignored
------- End of Included file bfffo.script
------- Included file bfffo.c
/* Word order */
enum {
MSW128,
NMSW128,
NLSW128,
LSW128
};
/* Unsigned only, because we don't need signs to multiply and divide. */
typedef unsigned int int128[4];
extern inline int fls (unsigned int a)
{
int r;
asm volatile ("bfffo %1{#0,#32},%0"
: "=d" (r) : "g" (a));
return r;
}
void normalize128 (int128 a)
{
int i,j;
i = !(a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]);
if (a[MSW128])
j = fls(a[MSW128]);
else if (a[NMSW128])
j = fls(a[NMSW128]) + 32;
/* XXX: it probably never gets beyond this point in actual use, but
that's indicative of a more general problem in the algorithm
(i.e. as per the actual 68881 implementation, we really only need
at most 67 bits of precision [plus overflow]) so I'm not going to
fix it. */
else if (a[NLSW128])
j = fls(a[NLSW128]) + 64;
else if (a[LSW128])
j = fls(a[LSW128]) + 96;
else
j = -1;
}
------- End of Included file bfffo.c
------- Included file bfffo.i
# 1 "bfffo.c"
enum {
MSW128,
NMSW128,
NLSW128,
LSW128
};
typedef unsigned int int128[4];
extern inline int fls (unsigned int a)
{
int r;
asm volatile ("bfffo %1{#0,#32},%0"
: "=d" (r) : "g" (a));
return r;
}
void normalize128 (int128 a)
{
int i,j;
i = !(a[LSW128] | a[NLSW128] | a[NMSW128] | a[MSW128]);
if (a[MSW128])
j = fls(a[MSW128]);
else if (a[NMSW128])
j = fls(a[NMSW128]) + 32;
else if (a[NLSW128])
j = fls(a[NLSW128]) + 64;
else if (a[LSW128])
j = fls(a[LSW128]) + 96;
else
j = -1;
}
------- End of Included file bfffo.i
------- Included file bfffo.s
.file "bfffo.c"
.version "01.01"
gcc2_compiled.:
.text
.align 2
.globl normalize128
.type normalize128,@function
normalize128:
move.l %d2,-(%sp)
move.l 8(%sp),%a0
move.l 12(%a0),%d2
move.l 8(%a0),%a1
move.l 4(%a0),%d1
move.l (%a0),%d0
jbeq .L3
#APP
bfffo %d0{#0,#32},%d0
#NO_APP
jbra .L5
.align 2
.L3:
tst.l %d1
jbeq .L6
#APP
bfffo %d1{#0,#32},%d0
#NO_APP
jbra .L5
.align 2
.L6:
tst.l %a1
jbeq .L9
#APP
bfffo %a1{#0,#32},%d0
#NO_APP
jbra .L5
.align 2
.L9:
tst.l %d2
jbeq .L5
#APP
bfffo %d2{#0,#32},%d0
#NO_APP
.L5:
move.l (%sp)+,%d2
rts
.Lfe1:
.size normalize128,.Lfe1-normalize128
.ident "GCC: (GNU) egcs-2.91.60 19981201 (egcs-1.1.1 release)"
------- End of Included file bfffo.s
More information about the Gcc-bugs
mailing list