123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190 |
- /* XL compiler hardware transactional execution intrinsics
- Copyright (C) 2013-2015 Free Software Foundation, Inc.
- Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
- This file is part of GCC.
- GCC is free software; you can redistribute it and/or modify it under
- the terms of the GNU General Public License as published by the Free
- Software Foundation; either version 3, or (at your option) any later
- version.
- GCC is distributed in the hope that it will be useful, but WITHOUT ANY
- WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
- You should have received a copy of the GNU General Public License
- along with GCC; see the file COPYING3. If not see
- <http://www.gnu.org/licenses/>. */
- #ifndef _HTMXLINTRIN_H
- #define _HTMXLINTRIN_H
- #include <stdint.h>
- #include <htmintrin.h>
- #ifdef __cplusplus
- extern "C" {
- #endif
- /* These intrinsics are being made available for compatibility with
- the IBM XL compiler. For documentation please see the "z/OS XL
- C/C++ Programming Guide" publicly available on the web. */
- /* FIXME: __TM_simple_begin and __TM_begin should be marked
- __always_inline__ as well but this currently produces an error
- since the tbegin builtins are "returns_twice" and setjmp_call_p
- (calls.c) therefore identifies the functions as calling setjmp.
- The tree inliner currently refuses to inline functions calling
- setjmp. */
- long
- __TM_simple_begin ()
- {
- return __builtin_tbegin_nofloat (0);
- }
- long
- __TM_begin (void* const tdb)
- {
- return __builtin_tbegin_nofloat (tdb);
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_end ()
- {
- return __builtin_tend ();
- }
- extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_abort ()
- {
- return __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE);
- }
- extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_named_abort (unsigned char const code)
- {
- return __builtin_tabort ((int)_HTM_FIRST_USER_ABORT_CODE + code);
- }
- extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_non_transactional_store (void* const addr, long long const value)
- {
- __builtin_non_tx_store ((uint64_t*)addr, (uint64_t)value);
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_nesting_depth (void* const tdb_ptr)
- {
- int depth = __builtin_tx_nesting_depth ();
- struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
- if (depth != 0)
- return depth;
- if (tdb->format != 1)
- return 0;
- return tdb->nesting_depth;
- }
- /* Transaction failure diagnostics */
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_is_user_abort (void* const tdb_ptr)
- {
- struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
- if (tdb->format != 1)
- return 0;
- return !!(tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE);
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_is_named_user_abort (void* const tdb_ptr, unsigned char* code)
- {
- struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
- if (tdb->format != 1)
- return 0;
- if (tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE)
- {
- *code = tdb->abort_code - _HTM_FIRST_USER_ABORT_CODE;
- return 1;
- }
- return 0;
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_is_illegal (void* const tdb_ptr)
- {
- struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
- return (tdb->format == 1
- && (tdb->abort_code == 4 /* unfiltered program interruption */
- || tdb->abort_code == 11 /* restricted instruction */));
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_is_footprint_exceeded (void* const tdb_ptr)
- {
- struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
- return (tdb->format == 1
- && (tdb->abort_code == 7 /* fetch overflow */
- || tdb->abort_code == 8 /* store overflow */));
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_is_nested_too_deep (void* const tdb_ptr)
- {
- struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
- return tdb->format == 1 && tdb->abort_code == 13; /* depth exceeded */
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_is_conflict (void* const tdb_ptr)
- {
- struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
- return (tdb->format == 1
- && (tdb->abort_code == 9 /* fetch conflict */
- || tdb->abort_code == 10 /* store conflict */));
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_is_failure_persistent (long const result)
- {
- return result == _HTM_TBEGIN_PERSISTENT;
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_failure_address (void* const tdb_ptr)
- {
- struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
- #ifdef __s390x__
- return tdb->atia;
- #else
- return tdb->atia & 0xffffffff;
- #endif
- }
- extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
- __TM_failure_code (void* const tdb_ptr)
- {
- struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
- return tdb->abort_code;
- }
- #ifdef __cplusplus
- }
- #endif
- #endif /* _HTMXLINTRIN_H */
|