Subject: The elink3 bug
To: None <port-i386@NetBSD.ORG>
From: Frank van der Linden <frank@wins.uva.nl>
List: port-i386
Date: 08/17/1997 23:37:53
I've done some investigating into the elink3 (ep driver) related crashes,
and found the following:

	- Removing the do { } while around mbuf macros did not result
	  in different code for elink3.o. Perhaps it avoided the problem
	  by changing code in other places slightly.
	- What was wrong, is the emitted code for bus_space_write_multi_X,
	  as also noted recently by Dave Huang (see message on tech-kern)
	- bus_space_write_multi_X clobbers the esi, ecx and eax
	  registers, and correctly marks them as such. It leaves
	  the choice for which register will point to the destination
	  up to gcc.
	- This seems to affect elink3.c in particular, because it
	  uses bus_space_write_multi (possibly) into PCI space.
	  The PIO part of bus_space_write_multi is fine.
	- Somehow, gcc picks eax, which is obviously incorrect, since
	  it as marked as clobbered (the lodsb instruction overwrites it)
	- What's also bad, is that the value that goes into eax is
	  a variable that was already 'appointed' to be a register
	  variable in edi, so it could just have used edi, and
	  saved itself a move instruction.
	- After individually disabling all extra optimizations that
	  -O2 uses over -O, I found that -fno-force-mem makes
	  gcc do the right thing. I can't be 100% sure that this
	  is the correct fix at the moment, but could people who have
	  had this problem perhaps try compiling their kernel with
	  -fno-force-mem and tell me what happens? This may apply to
	  other weird bugs too.

- Frank