Add an implementation for the CRIS and CRISv32 architectures, by Peter

* configure.in:
        * glib/gatomic.c: Add an implementation for the CRIS and CRISv32
        architectures, by Peter Kjellerstedt


svn path=/trunk/; revision=7732
This commit is contained in:
Matthias Clasen 2008-12-08 04:27:37 +00:00
parent bb63c612bf
commit 154fe24134
3 changed files with 144 additions and 2 deletions

View File

@ -1,3 +1,11 @@
2008-12-07 Matthias Clasen <mclasen@redhat.com>
Bug 508021 Add support for the CRIS and CRISv32 architectures
* configure.in:
* glib/gatomic.c: Add an implementation for the CRIS and CRISv32
architectures, by Peter Kjellerstedt
2008-12-02 Matthias Clasen <mclasen@redhat.com>
* glib/gkeyfile.c: Some more documentation additions.

View File

@ -2404,6 +2404,18 @@ if test x"$GCC" = xyes; then
[arm atomic implementation])
glib_memory_barrier_needed=no
;;
crisv32*|etraxfs*)
AC_MSG_RESULT([crisv32])
AC_DEFINE_UNQUOTED(G_ATOMIC_CRISV32, 1,
[crisv32 atomic implementation])
glib_memory_barrier_needed=no
;;
cris*|etrax*)
AC_MSG_RESULT([cris])
AC_DEFINE_UNQUOTED(G_ATOMIC_CRIS, 1,
[cris atomic implementation])
glib_memory_barrier_needed=no
;;
*)
AC_MSG_RESULT([none])
glib_memory_barrier_needed=yes

View File

@ -651,9 +651,131 @@ g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic,
return result;
}
# else /* !G_ATOMIC_ARM */
# elif defined (G_ATOMIC_CRIS) || defined (G_ATOMIC_CRISV32)
# ifdef G_ATOMIC_CRIS
# define CRIS_ATOMIC_INT_CMP_XCHG(atomic, oldval, newval) \
({ \
gboolean __result; \
__asm__ __volatile__ ("\n" \
"0:\tclearf\n\t" \
"cmp.d [%[Atomic]], %[OldVal]\n\t" \
"bne 1f\n\t" \
"ax\n\t" \
"move.d %[NewVal], [%[Atomic]]\n\t" \
"bwf 0b\n" \
"1:\tseq %[Result]" \
: [Result] "=&r" (__result), \
"=m" (*(atomic)) \
: [Atomic] "r" (atomic), \
[OldVal] "r" (oldval), \
[NewVal] "r" (newval), \
"g" (*(gpointer*) (atomic)) \
: "memory"); \
__result; \
})
# else
# define CRIS_ATOMIC_INT_CMP_XCHG(atomic, oldval, newval) \
({ \
gboolean __result; \
__asm__ __volatile__ ("\n" \
"0:\tclearf p\n\t" \
"cmp.d [%[Atomic]], %[OldVal]\n\t" \
"bne 1f\n\t" \
"ax\n\t" \
"move.d %[NewVal], [%[Atomic]]\n\t" \
"bcs 0b\n" \
"1:\tseq %[Result]" \
: [Result] "=&r" (__result), \
"=m" (*(atomic)) \
: [Atomic] "r" (atomic), \
[OldVal] "r" (oldval), \
[NewVal] "r" (newval), \
"g" (*(gpointer*) (atomic)) \
: "memory"); \
__result; \
})
# endif
#define CRIS_CACHELINE_SIZE 32
#define CRIS_ATOMIC_BREAKS_CACHELINE(atomic) \
(((gulong)(atomic) & (CRIS_CACHELINE_SIZE - 1)) > (CRIS_CACHELINE_SIZE - sizeof (atomic)))
gint __g_atomic_int_exchange_and_add (volatile gint *atomic,
gint val);
void __g_atomic_int_add (volatile gint *atomic,
gint val);
gboolean __g_atomic_int_compare_and_exchange (volatile gint *atomic,
gint oldval,
gint newval);
gboolean __g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic,
gpointer oldval,
gpointer newval);
gboolean
g_atomic_pointer_compare_and_exchange (volatile gpointer *atomic,
gpointer oldval,
gpointer newval)
{
if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
return __g_atomic_pointer_compare_and_exchange (atomic, oldval, newval);
return CRIS_ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
}
gboolean
g_atomic_int_compare_and_exchange (volatile gint *atomic,
gint oldval,
gint newval)
{
if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
return __g_atomic_int_compare_and_exchange (atomic, oldval, newval);
return CRIS_ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
}
gint
g_atomic_int_exchange_and_add (volatile gint *atomic,
gint val)
{
gint result;
if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
return __g_atomic_int_exchange_and_add (atomic, val);
do
result = *atomic;
while (!CRIS_ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
return result;
}
void
g_atomic_int_add (volatile gint *atomic,
gint val)
{
gint result;
if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
return __g_atomic_int_add (atomic, val);
do
result = *atomic;
while (!CRIS_ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
}
/* We need the atomic mutex for atomic operations where the atomic variable
* breaks the 32 byte cache line since the CRIS architecture does not support
* atomic operations on such variables. Fortunately this should be rare.
*/
# define DEFINE_WITH_MUTEXES
# endif /* G_ATOMIC_IA64 */
# define g_atomic_int_exchange_and_add __g_atomic_int_exchange_and_add
# define g_atomic_int_add __g_atomic_int_add
# define g_atomic_int_compare_and_exchange __g_atomic_int_compare_and_exchange
# define g_atomic_pointer_compare_and_exchange __g_atomic_pointer_compare_and_exchange
# else /* !G_ATOMIC_* */
# define DEFINE_WITH_MUTEXES
# endif /* G_ATOMIC_* */
#else /* !__GNUC__ */
# ifdef G_PLATFORM_WIN32
# define DEFINE_WITH_WIN32_INTERLOCKED