Imported Upstream version 4.8.1
[platform/upstream/gcc48.git] / libitm / config / x86 / target.h
index 5c7e6fb..77b627f 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;
+#ifdef __x86_64__
   unsigned long long rbx;
   unsigned long long rbp;
   unsigned long long r12;
@@ -36,18 +40,14 @@ typedef struct gtm_jmpbuf
   unsigned long long r14;
   unsigned long long r15;
   unsigned long long rip;
-} gtm_jmpbuf;
 #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,22 +63,69 @@ typedef struct gtm_jmpbuf
 static inline void
 cpu_relax (void)
 {
-  __asm volatile ("rep; nop" : : : "memory");
+  __builtin_ia32_pause ();
 }
 
-} // namespace GTM
+// 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
 
-// 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_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)
+{
+  return begin_ret == _XBEGIN_STARTED;
+}
+
+static inline void
+htm_commit ()
+{
+  _xend();
+}
+
+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);
+}
+
+static inline bool
+htm_abort_should_retry (uint32_t begin_ret)
+{
+  return begin_ret & _XABORT_RETRY;
+}
 #endif
+
+
+} // namespace GTM