This is the mail archive of the
gcc-prs@gcc.gnu.org
mailing list for the GCC project.
Re: libstdc++/5198: 3.0.3 linux x m68k build fail: invalid opcodes in c++locale.cc
- From: "Aaron J. Grier" <aaron at frye dot com>
- To: nobody at gcc dot gnu dot org
- Cc: gcc-prs at gcc dot gnu dot org,
- Date: 8 Jan 2002 21:56:02 -0000
- Subject: Re: libstdc++/5198: 3.0.3 linux x m68k build fail: invalid opcodes in c++locale.cc
- Reply-to: "Aaron J. Grier" <aaron at frye dot com>
The following reply was made to PR libstdc++/5198; it has been noted by GNATS.
From: "Aaron J. Grier" <aaron@frye.com>
To: libstdc++@gcc.gnu.org
Cc: rodrigc@gcc.gnu.org, gcc-gnats@gcc.gnu.org
Subject: Re: libstdc++/5198: 3.0.3 linux x m68k build fail: invalid opcodes in c++locale.cc
Date: Tue, 8 Jan 2002 13:51:28 -0800
--bX/mw5riLlTkt+Gv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline
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
--bX/mw5riLlTkt+Gv
Content-Type: text/plain; charset=us-ascii
Content-Disposition: attachment; filename="atomicity.diff"
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 */
-
-
--bX/mw5riLlTkt+Gv--