Sender: schwab@LS5.informatik.uni-dortmund.de
To: Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de>
Cc: linux-m68k@lists.linux-m68k.org
Subject: Re: SCC_ACCESS_INIT macro problem (was L68K: SCC bug with oops)
References: <199805290850.KAA09174@faui22c.informatik.uni-erlangen.de>
X-Yow: I want to TAKE IT HOME and DRESS IT UP in HOT PANTS!!
From: Andreas Schwab <schwab@LS5.informatik.uni-dortmund.de>
Date: 02 Jun 1998 10:33:44 +0200

Roman Hodek <Roman.Hodek@informatik.uni-erlangen.de> writes:

|> The asm is wrong here. The and insn overwrites the previous value of
|> %d0, but %d0 is not listed in the outputs, so gcc doesn't know this.
|> My fault... I've written that macro :-) The fix is to copy the value
|> of _SCC_p to some tmp variable and declare that it in the outputs so
|> gcc doesn't reuse the value.

That should teach you that such micro optimizations are not worth the
effort.  Rewriting that in C gives just as good code, but is much better
maintainable.

Andreas.

----------------------------------------------------------------------
--- linux/drivers/char/atari_SCC.h.~2~	Sat May 30 12:21:59 1998
+++ linux/drivers/char/atari_SCC.h	Sat May 30 12:49:07 1998
@@ -589,20 +589,11 @@
 	return rv;
 }
 
-#define SCC_ACCESS_INIT(info)												\
-	volatile struct PARTIAL_SCC *_SCC_p =									\
-		(volatile struct PARTIAL_SCC *)info->port;							\
-	unsigned char *_SCC_shadow =											\
-		({  unsigned char *_rv = (unsigned char *)SCC_shadow;				\
-			volatile struct PARTIAL_SCC *_tmp = _SCC_p;						\
-			/* gcc generates suboptimal code for this, so I use an asm */	\
-			__asm__ ( "and.l #4,%1; lea %0@(%1:l:4),%0"						\
-					  /* alternative: lea %za0@(%2,%1:l:4),%0				\
-					   * what's faster? */									\
-					  : "=&a" (_rv), "=&d" (_tmp)							\
-					  : "1" (_tmp), "0" (_rv) );							\
-			_rv;															\
-		})
+#define SCC_ACCESS_INIT(info)						\
+	volatile struct PARTIAL_SCC *_SCC_p =				\
+		(volatile struct PARTIAL_SCC *)info->port;		\
+	unsigned char *_SCC_shadow =					\
+		&SCC_shadow[(info->port >> 2) & 1][0]
 
 #define	SCCwrite(reg,val)		_SCCwrite(_SCC_p,_SCC_shadow,scc_del,(reg),(val),1)
 #define	SCCwrite_NB(reg,val)	_SCCwrite(_SCC_p,_SCC_shadow,scc_del,(reg),(val),0)
