X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=hs-boehmgc.git;a=blobdiff_plain;f=gc-7.2%2Flibatomic_ops%2Fsrc%2Fatomic_ops%2Fsysdeps%2Fgcc%2Fmips.h;fp=gc-7.2%2Flibatomic_ops%2Fsrc%2Fatomic_ops%2Fsysdeps%2Fgcc%2Fmips.h;h=527a34741a663fab11582e0bfbab36120533c90a;hp=0000000000000000000000000000000000000000;hb=324587ba93dc77f37406d41fd2a20d0e0d94fb1d;hpb=2a4ea609491b225a1ceb06da70396e93916f137a diff --git a/gc-7.2/libatomic_ops/src/atomic_ops/sysdeps/gcc/mips.h b/gc-7.2/libatomic_ops/src/atomic_ops/sysdeps/gcc/mips.h new file mode 100644 index 0000000..527a347 --- /dev/null +++ b/gc-7.2/libatomic_ops/src/atomic_ops/sysdeps/gcc/mips.h @@ -0,0 +1,102 @@ +/* + * Copyright (c) 2005,2007 Thiemo Seufer + * + * THIS MATERIAL IS PROVIDED AS IS, WITH ABSOLUTELY NO WARRANTY EXPRESSED + * OR IMPLIED. ANY USE IS AT YOUR OWN RISK. + * + * Permission is hereby granted to use or copy this program + * for any purpose, provided the above notices are retained on all copies. + * Permission to modify the code and to distribute modified code is granted, + * provided the above notices are retained, and a notice that the code was + * modified is included with the above copyright notice. + */ + +/* + * FIXME: This should probably make finer distinctions. SGI MIPS is + * much more strongly ordered, and in fact closer to sequentially + * consistent. This is really aimed at modern embedded implementations. + * It looks to me like this assumes a 32-bit ABI. -HB + */ + +#include "../all_aligned_atomic_load_store.h" +#include "../acquire_release_volatile.h" +#include "../test_and_set_t_is_ao_t.h" +#include "../standard_ao_double_t.h" + +/* Data dependence does not imply read ordering. */ +#define AO_NO_DD_ORDERING + +AO_INLINE void +AO_nop_full(void) +{ + __asm__ __volatile__( + " .set push \n" + " .set mips2 \n" + " .set noreorder \n" + " .set nomacro \n" + " sync \n" + " .set pop " + : : : "memory"); +} +#define AO_HAVE_nop_full + +AO_INLINE int +AO_compare_and_swap(volatile AO_t *addr, AO_t old, AO_t new_val) +{ + register int was_equal = 0; + register int temp; + + __asm__ __volatile__( + " .set push \n" + " .set mips2 \n" + " .set noreorder \n" + " .set nomacro \n" + "1: ll %0, %1 \n" + " bne %0, %4, 2f \n" + " move %0, %3 \n" + " sc %0, %1 \n" + " .set pop \n" + " beqz %0, 1b \n" + " li %2, 1 \n" + "2: " + : "=&r" (temp), "+R" (*addr), "+r" (was_equal) + : "r" (new_val), "r" (old) + : "memory"); + return was_equal; +} +#define AO_HAVE_compare_and_swap + +/* FIXME: I think the implementations below should be automatically */ +/* generated if we omit them. - HB */ + +AO_INLINE int +AO_compare_and_swap_acquire(volatile AO_t *addr, AO_t old, AO_t new_val) { + int result = AO_compare_and_swap(addr, old, new_val); + AO_nop_full(); + return result; +} +#define AO_HAVE_compare_and_swap_acquire + +AO_INLINE int +AO_compare_and_swap_release(volatile AO_t *addr, AO_t old, AO_t new_val) { + AO_nop_full(); + return AO_compare_and_swap(addr, old, new_val); +} +#define AO_HAVE_compare_and_swap_release + +AO_INLINE int +AO_compare_and_swap_full(volatile AO_t *addr, AO_t old, AO_t new_val) { + int result; + AO_nop_full(); + result = AO_compare_and_swap(addr, old, new_val); + AO_nop_full(); + return result; +} +#define AO_HAVE_compare_and_swap_full + +/* + * FIXME: We should also implement fetch_and_add and or primitives + * directly. + */ + +#include "../ao_t_is_int.h"