/* XL compiler hardware transactional execution intrinsics Copyright (C) 2013-2014 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 . */ #ifndef _HTMXLINTRIN_H #define _HTMXLINTRIN_H #include #include #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 */