diff options
Diffstat (limited to 'libitm/config/powerpc/target.h')
-rw-r--r-- | libitm/config/powerpc/target.h | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/libitm/config/powerpc/target.h b/libitm/config/powerpc/target.h index 67c02188452..cf01a57248d 100644 --- a/libitm/config/powerpc/target.h +++ b/libitm/config/powerpc/target.h @@ -22,6 +22,10 @@ see the files COPYING3 and COPYING.RUNTIME respectively. If not, see <http://www.gnu.org/licenses/>. */ +#ifdef HAVE_SYS_AUXV_H +#include <sys/auxv.h> +#endif + namespace GTM HIDDEN { typedef int v128 __attribute__((vector_size(16), may_alias, aligned(16))); @@ -55,4 +59,82 @@ cpu_relax (void) __asm volatile ("" : : : "memory"); } +// Use HTM if it is supported by the system. +// See gtm_thread::begin_transaction for how these functions are used. +#if defined (__linux__) \ + && defined (HAVE_AS_HTM) \ + && defined (HAVE_GETAUXVAL) \ + && defined (AT_HWCAP2) \ + && defined (PPC_FEATURE2_HAS_HTM) + +#include <htmintrin.h> + +#define USE_HTM_FASTPATH + +#define _TBEGIN_STARTED 0 +#define _TBEGIN_INDETERMINATE 1 +#define _TBEGIN_PERSISTENT 2 + +/* Number of retries for transient failures. */ +#define _HTM_RETRIES 10 + +static inline bool +htm_available (void) +{ + return (getauxval (AT_HWCAP2) & PPC_FEATURE2_HAS_HTM) ? true : false; +} + +static inline uint32_t +htm_init (void) +{ + // Maximum number of times we try to execute a transaction + // as a HW transaction. + return htm_available () ? _HTM_RETRIES : 0; +} + +static inline uint32_t +htm_begin (void) +{ + if (__builtin_expect (__builtin_tbegin (0), 1)) + return _TBEGIN_STARTED; + + if (_TEXASRU_FAILURE_PERSISTENT (__builtin_get_texasru ())) + return _TBEGIN_PERSISTENT; + + return _TBEGIN_INDETERMINATE; +} + +static inline bool +htm_begin_success (uint32_t begin_ret) +{ + return begin_ret == _TBEGIN_STARTED; +} + +static inline void +htm_commit (void) +{ + __builtin_tend (0); +} + +static inline void +htm_abort (void) +{ + __builtin_tabort (0); +} + +static inline bool +htm_abort_should_retry (uint32_t begin_ret) +{ + return begin_ret != _TBEGIN_PERSISTENT; +} + +/* Returns true iff a hardware transaction is currently being executed. */ +static inline bool +htm_transaction_active (void) +{ + return (_HTM_STATE (__builtin_ttest ()) == _HTM_TRANSACTIONAL); +} + +#endif + } // namespace GTM |