m68k problem and libstdc++

Craig Rodrigues rodrigc@mediaone.net
Sat Jan 12 04:08:00 GMT 2002


Hi,

The following patch and commentary was submitted by
Aaron Grier in response to PR 5198 (libstdc++ failing
to compile on m68k target).

Comments?
-- 
Craig Rodrigues        
http://www.gis.net/~craigr    
rodrigc@mediaone.net          



I think I've got a preliminary fix for this which handles the multilib
case -- see the attached patch.  unfortunately I can't do in-depth
testing at the moment since I'm having problems building my test target
(m68k-rtems).

I'm still not clear what to do for the 68000 and similarly atomically-
addled friends where it may be a priviliged operation to disable
interrupts.  (atomic lock via OS call, perhaps?)

I had to guess on some of the #defines; I don't think gcc uses m5300 or
m5400, although it probably should, and it may not be safe to turn off
interrupts even if __embedded__ is defined...  but such is the reason
patches are presented for peer reviewal.  :)

-- 
  Aaron J. Grier  |   Frye Electronics, Tigard, OR   |  aaron@frye.com
     "In a few thousand years people will be scratching their heads
       wondering how on earth the first computer was invented and
          bootstrapped without a prior computer to do it with."
                    --  Chris Malcolm, on comp.arch


Index: libstdc++-v3/config/cpu/m68k/bits/atomicity.h
===================================================================
RCS file: /cvs/gcc/egcs/libstdc++-v3/config/cpu/m68k/bits/atomicity.h,v
retrieving revision 1.2
diff -u -r1.2 atomicity.h
--- atomicity.h	2001/08/15 16:00:45	1.2
+++ atomicity.h	2002/01/08 18:22:32
@@ -1,6 +1,6 @@
-// Low-level functions for atomic operations: m680x0, x >= 2 version -*- C++ -*-
+// Low-level functions for atomic operations: generic M68k version  -*- C++ -*-
 
-// Copyright (C) 2001 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001, 2002 Free Software Foundation, Inc.
 //
 // This file is part of the GNU ISO C++ Library.  This library is free
 // software; you can redistribute it and/or modify it under the
@@ -27,17 +27,51 @@
 // invalidate any other reasons why the executable file might be covered by
 // the GNU General Public License.
 
+// there are three cases for m68k-variants I (ajg) am aware of that this
+// file needs to take care of:
+// * variants with the "cas" instruction
+//   68020/30/40/60
+// * variants with the "tas" instruction
+//   cpu32, 5400
+// * variants with no atomic read/modify/write instruction at all
+//   68000/10, 5200/300
+//
+// code for cas method was pre-existing, tas method was written by
+// Aaron J. Grier <aaron@frye.com>, and interrupt disable method comes
+// from Eric Norum <eric@cls.usask.ca> and
+// Joel Sherrill <joel.sherrill@oarcorp.com>
+
 #ifndef _BITS_ATOMICITY_H
 #define _BITS_ATOMICITY_H	1
 
 typedef int _Atomic_word;
+
+// atomically increment *__mem by __val and return the old *__mem
 
-static inline _Atomic_word 
+static inline _Atomic_word
 __attribute__ ((__unused__))
 __exchange_and_add (volatile _Atomic_word *__mem, int __val)
 {
   register _Atomic_word __result = *__mem;
+
+#if defined(__mcpu32__) || defined(__mcf5400__)
+  static char __lock = 0;	// needs to be a byte
+
+  // tas method
+  __asm__ __volatile__ ( "1: tas %1;"
+		 	 "   jbne 1b;"
+			 "   move%.l %3, %0;"
+			 "   add%.l %2, %3;"
+			 "   clrb %1;"
+			 : "=d" (__result), "=m" (__lock)
+			 : "d" (__val), "m" (*__mem), "0" (__result)
+			 : "memory");
+#else
+#if defined(__mc68020__) || defined(__mc68030__) \
+  || defined(__mc68040__) || defined(__mc68060__)
   register _Atomic_word __temp;
+
+  // cas method
   __asm__ __volatile__ ("1: move%.l %0,%1;"
 			"   add%.l %2,%1;"
 			"   cas%.l %0,%1,%3;"
@@ -46,16 +80,52 @@
 			: "d" (__val), "m" (*__mem), "0" (__result)
 			: "memory");
   return __result;
+#else
+#if defined(__rtems__) || defined(__vxWorks__) || defined(__embedded__)
+  volatile short __level;
+#if defined(__mcf5200__) || defined(__mcf5300__)
+  // coldfire v2 / v3 interrupt disable
+  unsigned int __tmpsr = 0x700;
+  __asm__ __volatile__ ( "move.w %%sr,%0;"
+			 "or.l   %0,%1;"
+			 "move.w %1,%%sr"
+			 : "=d" (__level), "=d"(__tmpsr)
+			 : "1"(__tmpsr) );
+#else
+  // generic 68000 interrupt disable
+  __asm__ __volatile__ ( "move.w  %%sr,%0;"
+			 "or.w    #0x0700,%%sr"
+	 		 : "=d" (__level) );
+#endif
+#else
+#warning __exchange_and_add is not atomic for current target
+#endif
+  __result = *__mem;
+  *__mem += __val;
+
+#if defined(__rtems__) || defined(__vxWorks__) || defined(__embedded__)
+  __asm__ __volatile__ ( "move.w  %0,%%sr " : : "d" (__level) );
+
+#endif
+#endif
+#endif
+
+  return __result;
 }
+
+// atomically increment *__mem
 
-static inline void
+static void
 __attribute__ ((__unused__))
 __atomic_add (volatile _Atomic_word* __mem, int __val)
 {
-  __asm__ __volatile__ ("add%.l %0,%1"
-			: : "id" (__val), "m" (*__mem) : "memory");
+  static unsigned char __lock;
+  _Atomic_word __tmp;
+
+  __asm__ __volatile__( "add%.l	%1,(%0)"
+			:
+			: "a" (__mem), "d" (__val)
+			: "memory" );
 }
 
 #endif /* atomicity.h */
-
-



More information about the Gcc mailing list