]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - libitm/config/x86/target.h
Update copyright in libitm.
[thirdparty/gcc.git] / libitm / config / x86 / target.h
index 197faebe2d4e71f549fb4959ed085657e332335e..77b627f95bbd14eff0bb4efab3678b33b768f85e 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2008, 2009, 2011 Free Software Foundation, Inc.
+/* Copyright (C) 2008-2013 Free Software Foundation, Inc.
    Contributed by Richard Henderson <rth@redhat.com>.
 
    This file is part of the GNU Transactional Memory Library (libitm).
    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
    <http://www.gnu.org/licenses/>.  */
 
+// We'll be using some of the cpu builtins, and their associated types.
+#include <x86intrin.h>
+#include <cpuid.h>
+
 namespace GTM HIDDEN {
 
-#ifdef __x86_64__
 /* ??? This doesn't work for Win64.  */
 typedef struct gtm_jmpbuf
 {
   void *cfa;
-  unsigned long rip;
-  unsigned long rbx;
-  unsigned long rbp;
-  unsigned long r12;
-  unsigned long r13;
-  unsigned long r14;
-  unsigned long r15;
-} gtm_jmpbuf;
+#ifdef __x86_64__
+  unsigned long long rbx;
+  unsigned long long rbp;
+  unsigned long long r12;
+  unsigned long long r13;
+  unsigned long long r14;
+  unsigned long long r15;
+  unsigned long long rip;
 #else
-typedef struct gtm_jmpbuf
-{
-  void *cfa;
   unsigned long ebx;
   unsigned long esi;
   unsigned long edi;
   unsigned long ebp;
   unsigned long eip;
-} gtm_jmpbuf;
 #endif
+} gtm_jmpbuf;
 
 /* x86 doesn't require strict alignment for the basic types.  */
 #define STRICT_ALIGNMENT 0
@@ -63,36 +63,69 @@ typedef struct gtm_jmpbuf
 static inline void
 cpu_relax (void)
 {
-  __asm volatile ("rep; nop" : : : "memory");
+  __builtin_ia32_pause ();
 }
 
-static inline void
-atomic_read_barrier (void)
+// Use Intel RTM if supported by the assembler.
+// See gtm_thread::begin_transaction for how these functions are used.
+#ifdef HAVE_AS_RTM
+#define USE_HTM_FASTPATH
+
+static inline bool
+htm_available ()
+{
+  const unsigned cpuid_rtm = bit_RTM;
+  if (__get_cpuid_max (0, NULL) >= 7)
+    {
+      unsigned a, b, c, d;
+      __cpuid_count (7, 0, a, b, c, d);
+      if (b & cpuid_rtm)
+       return true;
+    }
+  return false;
+}
+
+static inline uint32_t
+htm_init ()
+{
+  // Maximum number of times we try to execute a transaction as a HW
+  // transaction.
+  // ??? Why 2?  Any offline or runtime tuning necessary?
+  return htm_available () ? 2 : 0;
+}
+
+static inline uint32_t
+htm_begin ()
+{
+  return _xbegin();
+}
+
+static inline bool
+htm_begin_success (uint32_t begin_ret)
 {
-  /* x86 is a strong memory ordering machine.  */
-  __asm volatile ("" : : : "memory");
+  return begin_ret == _XBEGIN_STARTED;
 }
 
 static inline void
-atomic_write_barrier (void)
+htm_commit ()
 {
-  /* x86 is a strong memory ordering machine.  */
-  __asm volatile ("" : : : "memory");
+  _xend();
 }
 
-} // namespace GTM
+static inline void
+htm_abort ()
+{
+  // ??? According to a yet unpublished ABI rule, 0xff is reserved and
+  // supposed to signal a busy lock.  Source: andi.kleen@intel.com
+  _xabort(0xff);
+}
 
-// We'll be using some of the cpu builtins, and their associated types.
-#ifndef __cplusplus
-/* ??? It's broken for C++. */
-#include <x86intrin.h>
-#else
-# ifdef __SSE2__
-#  include <emmintrin.h>
-# elif defined(__SSE__)
-#  include <xmmintrin.h>
-# endif
-# ifdef __AVX__
-#  include <immintrin.h>
-# endif
+static inline bool
+htm_abort_should_retry (uint32_t begin_ret)
+{
+  return begin_ret & _XABORT_RETRY;
+}
 #endif
+
+
+} // namespace GTM