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