From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 25090 invoked by alias); 8 Jan 2002 21:56:02 -0000 Mailing-List: contact gcc-prs-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Archive: List-Post: List-Help: Sender: gcc-prs-owner@gcc.gnu.org Received: (qmail 25066 invoked by uid 71); 8 Jan 2002 21:56:02 -0000 Date: Tue, 08 Jan 2002 13:56:00 -0000 Message-ID: <20020108215602.25061.qmail@sources.redhat.com> To: nobody@gcc.gnu.org Cc: gcc-prs@gcc.gnu.org, From: "Aaron J. Grier" Subject: Re: libstdc++/5198: 3.0.3 linux x m68k build fail: invalid opcodes in c++locale.cc Reply-To: "Aaron J. Grier" X-SW-Source: 2002-01/txt/msg00345.txt.bz2 List-Id: The following reply was made to PR libstdc++/5198; it has been noted by GNATS. From: "Aaron J. Grier" 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 , and interrupt disable method comes +// from Eric Norum and +// Joel Sherrill + #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--