This is the mail archive of the gcc-prs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: libstdc++/5198: 3.0.3 linux x m68k build fail: invalid opcodes in c++locale.cc


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--


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]