* src/atomic_ops/sysdeps/msftc/x86_64.h: New file.
* src/atomic_ops.h: Add test for msftc/x86_64.h.
* src/atomic_ops/sysdeps/msftc/x86.h: Complain for _WIN64.
* src/atomic_ops/sysdeps/Makefile.am: Add x86_64.h.
* src/atomic_ops/sysdeps/Makefile.in: Regenerate.
* src/atomic_ops/sysdeps/aligned_atomic_load_store.h,
src/atomic_ops/sysdeps/int_aligned_atomic_load_store.h,
src/atomic_ops/sysdeps/short_aligned_atomic_load_store.h:
Replace unsigned long cast with size_t.
+2007-06-06 Hans Boehm <Hans.Boehm@hp.com>
+ * src/atomic_ops/sysdeps/msftc/x86_64.h: New file.
+ * src/atomic_ops.h: Add test for msftc/x86_64.h.
+ * src/atomic_ops/sysdeps/msftc/x86.h: Complain for _WIN64.
+ * src/atomic_ops/sysdeps/Makefile.am: Add x86_64.h.
+ * src/atomic_ops/sysdeps/Makefile.in: Regenerate.
+ * src/atomic_ops/sysdeps/aligned_atomic_load_store.h,
+ src/atomic_ops/sysdeps/int_aligned_atomic_load_store.h,
+ src/atomic_ops/sysdeps/short_aligned_atomic_load_store.h:
+ Replace unsigned long cast with size_t.
+
2007-05-17 Hans Boehm <Hans.Boehm@hp.com>
* src/atomic_ops/sysdeps/gcc/hppa.h (AO_test_and_set_full):
Add cast for return.
/* atomic_ops_generalize.h. */
/* Some common defaults. Overridden for some architectures. */
-#define AO_t unsigned long
- /* Could conceivably be redefined below if/when we add */
- /* win64 support. */
+#define AO_t size_t
/* The test_and_set primitive returns an AO_TS_VAL_t value. */
/* AO_TS_t is the type of an in-memory test-and-set location. */
#if defined(__GNUC__) && !defined(__INTEL_COMPILER)
# define AO_compiler_barrier() __asm__ __volatile__("" : : : "memory")
#elif defined(_MSC_VER)
-# define AO_compiler_barrier() __asm { }
+# if defined(_AMD64_)
+# pragma intrinsic(_ReadWriteBarrier)
+# define AO_compiler_barrier() _ReadWriteBarrier()
+ /* We assume this does not generate a fence instruction. */
+ /* The documentation is a bit unclear. */
+# else
+# define AO_compiler_barrier() __asm { }
+ /* The preceding implementation may be preferable here too. */
+ /* But the documentation warns about VC++ 2003 and earlier. */
+# endif
#elif defined(__INTEL_COMPILER)
# define AO_compiler_barrier() __memory_barrier() /* Too strong? IA64-only? */
#elif defined(_HPUX_SOURCE)
#endif
#if defined(_MSC_VER)
-# if _M_IX86 >= 400
+# if defined(_AMD64_)
+# include "atomic_ops/sysdeps/msftc/x86_64.h"
+# elif _M_IX86 >= 400
# include "atomic_ops/sysdeps/msftc/x86.h"
# endif
#endif
icc/ia64.h \
\
msftc/x86.h \
+ msftc/x86_64.h \
\
hpc/ia64.h hpc/hppa.h \
\
-# Makefile.in generated by automake 1.9.3 from Makefile.am.
+# Makefile.in generated by automake 1.9.6 from Makefile.am.
# @configure_input@
# Copyright (C) 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001, 2002,
-# 2003, 2004 Free Software Foundation, Inc.
+# 2003, 2004, 2005 Free Software Foundation, Inc.
# This Makefile.in is free software; the Free Software Foundation
# gives unlimited permission to copy and/or distribute it,
# with or without modifications, as long as this notice is preserved.
ECHO_T = @ECHO_T@
EGREP = @EGREP@
EXEEXT = @EXEEXT@
+GREP = @GREP@
INSTALL_DATA = @INSTALL_DATA@
INSTALL_PROGRAM = @INSTALL_PROGRAM@
INSTALL_SCRIPT = @INSTALL_SCRIPT@
STRIP = @STRIP@
VERSION = @VERSION@
ac_ct_CC = @ac_ct_CC@
-ac_ct_RANLIB = @ac_ct_RANLIB@
-ac_ct_STRIP = @ac_ct_STRIP@
am__fastdepCC_FALSE = @am__fastdepCC_FALSE@
am__fastdepCC_TRUE = @am__fastdepCC_TRUE@
am__include = @am__include@
build_os = @build_os@
build_vendor = @build_vendor@
datadir = @datadir@
+datarootdir = @datarootdir@
+docdir = @docdir@
+dvidir = @dvidir@
exec_prefix = @exec_prefix@
host = @host@
host_alias = @host_alias@
host_cpu = @host_cpu@
host_os = @host_os@
host_vendor = @host_vendor@
+htmldir = @htmldir@
includedir = @includedir@
infodir = @infodir@
install_sh = @install_sh@
libdir = @libdir@
libexecdir = @libexecdir@
+localedir = @localedir@
localstatedir = @localstatedir@
mandir = @mandir@
mkdir_p = @mkdir_p@
oldincludedir = @oldincludedir@
+pdfdir = @pdfdir@
prefix = @prefix@
program_transform_name = @program_transform_name@
+psdir = @psdir@
sbindir = @sbindir@
sharedstatedir = @sharedstatedir@
sysconfdir = @sysconfdir@
icc/ia64.h \
\
msftc/x86.h \
+ msftc/x86_64.h \
\
hpc/ia64.h hpc/hppa.h \
\
AO_INLINE AO_t
AO_load(volatile AO_t *addr)
{
- assert(((unsigned long)addr & (sizeof(AO_t) - 1)) == 0);
+ assert(((size_t)addr & (sizeof(AO_t) - 1)) == 0);
/* Cast away the volatile for architectures where */
/* volatile adds barrier semantics. */
return *(AO_t *)addr;
AO_INLINE void
AO_store(volatile AO_t *addr, AO_t new_val)
{
- assert(((unsigned long)addr & (sizeof(AO_t) - 1)) == 0);
+ assert(((size_t)addr & (sizeof(AO_t) - 1)) == 0);
(*(AO_t *)addr) = new_val;
}
AO_INLINE unsigned int
AO_int_load(volatile unsigned int *addr)
{
- assert(((unsigned long)addr & (sizeof(unsigned int) - 1)) == 0);
+ assert(((size_t)addr & (sizeof(unsigned int) - 1)) == 0);
/* Cast away the volatile for architectures like IA64 where */
/* volatile adds barrier semantics. */
return (*(unsigned int *)addr);
AO_INLINE void
AO_int_store(volatile unsigned int *addr, unsigned int new_val)
{
- assert(((unsigned long)addr & (sizeof(unsigned int) - 1)) == 0);
+ assert(((size_t)addr & (sizeof(unsigned int) - 1)) == 0);
(*(unsigned int *)addr) = new_val;
}
#define AO_HAVE_compare_and_swap_full
#endif /* ASSUME_WINDOWS98 */
-#ifndef _WIN64
-#include "../ao_t_is_int.h"
+#ifdef _WIN64
+# error wrong architecture
#endif
+
+#include "../ao_t_is_int.h"
--- /dev/null
+/*
+ * Copyright (c) 2003 Hewlett-Packard Development Company, L.P.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+/* The following really assume we have a 486 or better. */
+/* If ASSUME_WINDOWS98 is defined, we assume Windows 98 or newer. */
+
+#include "../all_aligned_atomic_load_store.h"
+
+/* Real X86 implementations, except for some old WinChips, appear */
+/* to enforce ordering between memory operations, EXCEPT that a later */
+/* read can pass earlier writes, presumably due to the visible */
+/* presence of store buffers. */
+/* We ignore both the WinChips, and the fact that the official specs */
+/* seem to be much weaker (and arguably too weak to be usable). */
+
+#include "../ordered_except_wr.h"
+
+#if 0
+FIXME: Need to reimplement testandset
+
+#include "../test_and_set_t_is_char.h"
+
+#else
+
+#include "../test_and_set_t_is_ao_t.h"
+
+#endif
+
+#include <windows.h>
+ /* Seems like over-kill, but that's what MSDN recommends. */
+ /* And apparently winbase.h is not always self-contained. */
+
+
+#include <intrin.h>
+
+#pragma intrinsic (_ReadWriteBarrier)
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+LONGLONG __cdecl _InterlockedIncrement64(LONGLONG volatile *Addend);
+LONGLONG __cdecl _InterlockedDecrement64(LONGLONG volatile *Addend);
+LONGLONG __cdecl _InterlockedExchangeAdd64(LONGLONG volatile* Target,
+ LONGLONG Addend);
+LONGLONG __cdecl _InterlockedExchange64(LONGLONG volatile* Target,
+ LONGLONG Value);
+LONGLONG __cdecl _InterlockedCompareExchange64(LONGLONG volatile* Dest,
+ LONGLONG Exchange,
+ LONGLONG Comp);
+
+#ifdef __cplusplus
+}
+#endif
+
+#pragma intrinsic (_InterlockedIncrement64)
+#pragma intrinsic (_InterlockedDecrement64)
+#pragma intrinsic (_InterlockedExchange64)
+#pragma intrinsic (_InterlockedExchangeAdd64)
+#pragma intrinsic (_InterlockedCompareExchange64)
+
+/* As far as we can tell, the lfence and sfence instructions are not */
+/* currently needed or useful for cached memory accesses. */
+
+/* Unfortunately mfence doesn't exist everywhere. */
+/* IsProcessorFeaturePresent(PF_COMPARE_EXCHANGE128) is */
+/* probably a conservative test for it? */
+
+#if defined(AO_USE_PENTIUM4_INSTRS)
+
+AO_INLINE void
+AO_nop_full()
+{
+ __asm { mfence }
+}
+
+#define AO_HAVE_nop_full
+
+#else
+
+/* We could use the cpuid instruction. But that seems to be slower */
+/* than the default implementation based on test_and_set_full. Thus */
+/* we omit that bit of misinformation here. */
+
+#endif
+
+AO_INLINE AO_t
+AO_fetch_and_add_full (volatile AO_t *p, AO_t incr)
+{
+ return _InterlockedExchangeAdd64((LONGLONG volatile *)p, (LONGLONG)incr);
+}
+
+#define AO_HAVE_fetch_and_add_full
+
+AO_INLINE AO_t
+AO_fetch_and_add1_full (volatile AO_t *p)
+{
+ return _InterlockedIncrement64((LONGLONG volatile *)p) - 1;
+}
+
+#define AO_HAVE_fetch_and_add1_full
+
+AO_INLINE AO_t
+AO_fetch_and_sub1_full (volatile AO_t *p)
+{
+ return _InterlockedDecrement64((LONGLONG volatile *)p) + 1;
+}
+
+#define AO_HAVE_fetch_and_sub1_full
+
+AO_INLINE int
+AO_compare_and_swap_full(volatile AO_t *addr,
+ AO_t old, AO_t new_val)
+{
+ return _InterlockedCompareExchange64((LONGLONG volatile *)addr,
+ (LONGLONG)new_val, (LONGLONG)old)
+ == (LONGLONG)old;
+}
+
+#define AO_HAVE_compare_and_swap_full
+
+#if 0
+FIXME: (__asm not supported)
+AO_INLINE AO_TS_VAL_t
+AO_test_and_set_full(volatile AO_TS_t *addr)
+{
+ __asm
+ {
+ mov eax,AO_TS_SET ;
+ mov ebx,addr ;
+ xchg byte ptr [ebx],al ;
+ }
+}
+
+#define AO_HAVE_test_and_set_full
+#endif
+
AO_INLINE unsigned short
AO_short_load(volatile unsigned short *addr)
{
- assert(((unsigned long)addr & (sizeof(unsigned short) - 1)) == 0);
+ assert(((size_t)addr & (sizeof(unsigned short) - 1)) == 0);
/* Cast away the volatile for architectures like IA64 where */
/* volatile adds barrier semantics. */
return (*(unsigned short *)addr);
AO_INLINE void
AO_short_store(volatile unsigned short *addr, unsigned short new_val)
{
- assert(((unsigned long)addr & (sizeof(unsigned short) - 1)) == 0);
+ assert(((size_t)addr & (sizeof(unsigned short) - 1)) == 0);
(*(unsigned short *)addr) = new_val;
}