Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. /*===---- htmxlintrin.h - XL compiler HTM execution intrinsics-------------===*\
  2.  *
  3.  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
  4.  * See https://llvm.org/LICENSE.txt for license information.
  5.  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
  6.  *
  7. \*===----------------------------------------------------------------------===*/
  8.  
  9. #ifndef __HTMXLINTRIN_H
  10. #define __HTMXLINTRIN_H
  11.  
  12. #ifndef __HTM__
  13. #error "HTM instruction set not enabled"
  14. #endif
  15.  
  16. #include <htmintrin.h>
  17.  
  18. #ifdef __powerpc__
  19.  
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23.  
  24. #define _TEXASR_PTR(TM_BUF) ((texasr_t *)((char *)(TM_BUF) + 0))
  25. #define _TEXASRU_PTR(TM_BUF) ((texasru_t *)((char *)(TM_BUF) + 0))
  26. #define _TEXASRL_PTR(TM_BUF) ((texasrl_t *)((char *)(TM_BUF) + 4))
  27. #define _TFIAR_PTR(TM_BUF) ((tfiar_t *)((char *)(TM_BUF) + 8))
  28.  
  29. typedef char TM_buff_type[16];
  30.  
  31. /* This macro can be used to determine whether a transaction was successfully
  32.    started from the __TM_begin() and __TM_simple_begin() intrinsic functions
  33.    below.  */
  34. #define _HTM_TBEGIN_STARTED     1
  35.  
  36. extern __inline long
  37. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  38. __TM_simple_begin (void)
  39. {
  40.   if (__builtin_expect (__builtin_tbegin (0), 1))
  41.     return _HTM_TBEGIN_STARTED;
  42.   return 0;
  43. }
  44.  
  45. extern __inline long
  46. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  47. __TM_begin (void* const __TM_buff)
  48. {
  49.   *_TEXASRL_PTR (__TM_buff) = 0;
  50.   if (__builtin_expect (__builtin_tbegin (0), 1))
  51.     return _HTM_TBEGIN_STARTED;
  52. #ifdef __powerpc64__
  53.   *_TEXASR_PTR (__TM_buff) = __builtin_get_texasr ();
  54. #else
  55.   *_TEXASRU_PTR (__TM_buff) = __builtin_get_texasru ();
  56.   *_TEXASRL_PTR (__TM_buff) = __builtin_get_texasr ();
  57. #endif
  58.   *_TFIAR_PTR (__TM_buff) = __builtin_get_tfiar ();
  59.   return 0;
  60. }
  61.  
  62. extern __inline long
  63. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  64. __TM_end (void)
  65. {
  66.   if (__builtin_expect (__builtin_tend (0), 1))
  67.     return 1;
  68.   return 0;
  69. }
  70.  
  71. extern __inline void
  72. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  73. __TM_abort (void)
  74. {
  75.   __builtin_tabort (0);
  76. }
  77.  
  78. extern __inline void
  79. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  80. __TM_named_abort (unsigned char const __code)
  81. {
  82.   __builtin_tabort (__code);
  83. }
  84.  
  85. extern __inline void
  86. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  87. __TM_resume (void)
  88. {
  89.   __builtin_tresume ();
  90. }
  91.  
  92. extern __inline void
  93. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  94. __TM_suspend (void)
  95. {
  96.   __builtin_tsuspend ();
  97. }
  98.  
  99. extern __inline long
  100. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  101. __TM_is_user_abort (void* const __TM_buff)
  102. {
  103.   texasru_t texasru = *_TEXASRU_PTR (__TM_buff);
  104.   return _TEXASRU_ABORT (texasru);
  105. }
  106.  
  107. extern __inline long
  108. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  109. __TM_is_named_user_abort (void* const __TM_buff, unsigned char *__code)
  110. {
  111.   texasru_t texasru = *_TEXASRU_PTR (__TM_buff);
  112.  
  113.   *__code = _TEXASRU_FAILURE_CODE (texasru);
  114.   return _TEXASRU_ABORT (texasru);
  115. }
  116.  
  117. extern __inline long
  118. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  119. __TM_is_illegal (void* const __TM_buff)
  120. {
  121.   texasru_t texasru = *_TEXASRU_PTR (__TM_buff);
  122.   return _TEXASRU_DISALLOWED (texasru);
  123. }
  124.  
  125. extern __inline long
  126. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  127. __TM_is_footprint_exceeded (void* const __TM_buff)
  128. {
  129.   texasru_t texasru = *_TEXASRU_PTR (__TM_buff);
  130.   return _TEXASRU_FOOTPRINT_OVERFLOW (texasru);
  131. }
  132.  
  133. extern __inline long
  134. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  135. __TM_nesting_depth (void* const __TM_buff)
  136. {
  137.   texasrl_t texasrl;
  138.  
  139.   if (_HTM_STATE (__builtin_ttest ()) == _HTM_NONTRANSACTIONAL)
  140.     {
  141.       texasrl = *_TEXASRL_PTR (__TM_buff);
  142.       if (!_TEXASR_FAILURE_SUMMARY (texasrl))
  143.         texasrl = 0;
  144.     }
  145.   else
  146.     texasrl = (texasrl_t) __builtin_get_texasr ();
  147.  
  148.   return _TEXASR_TRANSACTION_LEVEL (texasrl);
  149. }
  150.  
  151. extern __inline long
  152. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  153. __TM_is_nested_too_deep(void* const __TM_buff)
  154. {
  155.   texasru_t texasru = *_TEXASRU_PTR (__TM_buff);
  156.   return _TEXASRU_NESTING_OVERFLOW (texasru);
  157. }
  158.  
  159. extern __inline long
  160. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  161. __TM_is_conflict(void* const __TM_buff)
  162. {
  163.   texasru_t texasru = *_TEXASRU_PTR (__TM_buff);
  164.   /* Return TEXASR bits 11 (Self-Induced Conflict) through
  165.      14 (Translation Invalidation Conflict).  */
  166.   return (_TEXASRU_EXTRACT_BITS (texasru, 14, 4)) ? 1 : 0;
  167. }
  168.  
  169. extern __inline long
  170. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  171. __TM_is_failure_persistent(void* const __TM_buff)
  172. {
  173.   texasru_t texasru = *_TEXASRU_PTR (__TM_buff);
  174.   return _TEXASRU_FAILURE_PERSISTENT (texasru);
  175. }
  176.  
  177. extern __inline long
  178. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  179. __TM_failure_address(void* const __TM_buff)
  180. {
  181.   return *_TFIAR_PTR (__TM_buff);
  182. }
  183.  
  184. extern __inline long long
  185. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  186. __TM_failure_code(void* const __TM_buff)
  187. {
  188.   return *_TEXASR_PTR (__TM_buff);
  189. }
  190.  
  191. #ifdef __cplusplus
  192. }
  193. #endif
  194.  
  195. #endif /* __powerpc__ */
  196.  
  197. #ifdef __s390__
  198.  
  199. #include <stdint.h>
  200.  
  201. /* These intrinsics are being made available for compatibility with
  202.    the IBM XL compiler.  For documentation please see the "z/OS XL
  203.    C/C++ Programming Guide" publicly available on the web.  */
  204.  
  205. static __inline long __attribute__((__always_inline__, __nodebug__))
  206. __TM_simple_begin ()
  207. {
  208.   return __builtin_tbegin_nofloat (0);
  209. }
  210.  
  211. static __inline long __attribute__((__always_inline__, __nodebug__))
  212. __TM_begin (void* const __tdb)
  213. {
  214.   return __builtin_tbegin_nofloat (__tdb);
  215. }
  216.  
  217. static __inline long __attribute__((__always_inline__, __nodebug__))
  218. __TM_end ()
  219. {
  220.   return __builtin_tend ();
  221. }
  222.  
  223. static __inline void __attribute__((__always_inline__))
  224. __TM_abort ()
  225. {
  226.   return __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE);
  227. }
  228.  
  229. static __inline void __attribute__((__always_inline__, __nodebug__))
  230. __TM_named_abort (unsigned char const __code)
  231. {
  232.   return __builtin_tabort ((int)_HTM_FIRST_USER_ABORT_CODE + __code);
  233. }
  234.  
  235. static __inline void __attribute__((__always_inline__, __nodebug__))
  236. __TM_non_transactional_store (void* const __addr, long long const __value)
  237. {
  238.   __builtin_non_tx_store ((uint64_t*)__addr, (uint64_t)__value);
  239. }
  240.  
  241. static __inline long __attribute__((__always_inline__, __nodebug__))
  242. __TM_nesting_depth (void* const __tdb_ptr)
  243. {
  244.   int depth = __builtin_tx_nesting_depth ();
  245.   struct __htm_tdb *tdb = (struct __htm_tdb*)__tdb_ptr;
  246.  
  247.   if (depth != 0)
  248.     return depth;
  249.  
  250.   if (tdb->format != 1)
  251.     return 0;
  252.   return tdb->nesting_depth;
  253. }
  254.  
  255. /* Transaction failure diagnostics */
  256.  
  257. static __inline long __attribute__((__always_inline__, __nodebug__))
  258. __TM_is_user_abort (void* const __tdb_ptr)
  259. {
  260.   struct __htm_tdb *tdb = (struct __htm_tdb*)__tdb_ptr;
  261.  
  262.   if (tdb->format != 1)
  263.     return 0;
  264.  
  265.   return !!(tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE);
  266. }
  267.  
  268. static __inline long __attribute__((__always_inline__, __nodebug__))
  269. __TM_is_named_user_abort (void* const __tdb_ptr, unsigned char* __code)
  270. {
  271.   struct __htm_tdb *tdb = (struct __htm_tdb*)__tdb_ptr;
  272.  
  273.   if (tdb->format != 1)
  274.     return 0;
  275.  
  276.   if (tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE)
  277.     {
  278.       *__code = tdb->abort_code - _HTM_FIRST_USER_ABORT_CODE;
  279.       return 1;
  280.     }
  281.   return 0;
  282. }
  283.  
  284. static __inline long __attribute__((__always_inline__, __nodebug__))
  285. __TM_is_illegal (void* const __tdb_ptr)
  286. {
  287.   struct __htm_tdb *tdb = (struct __htm_tdb*)__tdb_ptr;
  288.  
  289.   return (tdb->format == 1
  290.           && (tdb->abort_code == 4 /* unfiltered program interruption */
  291.               || tdb->abort_code == 11 /* restricted instruction */));
  292. }
  293.  
  294. static __inline long __attribute__((__always_inline__, __nodebug__))
  295. __TM_is_footprint_exceeded (void* const __tdb_ptr)
  296. {
  297.   struct __htm_tdb *tdb = (struct __htm_tdb*)__tdb_ptr;
  298.  
  299.   return (tdb->format == 1
  300.           && (tdb->abort_code == 7 /* fetch overflow */
  301.               || tdb->abort_code == 8 /* store overflow */));
  302. }
  303.  
  304. static __inline long __attribute__((__always_inline__, __nodebug__))
  305. __TM_is_nested_too_deep (void* const __tdb_ptr)
  306. {
  307.   struct __htm_tdb *tdb = (struct __htm_tdb*)__tdb_ptr;
  308.  
  309.   return tdb->format == 1 && tdb->abort_code == 13; /* depth exceeded */
  310. }
  311.  
  312. static __inline long __attribute__((__always_inline__, __nodebug__))
  313. __TM_is_conflict (void* const __tdb_ptr)
  314. {
  315.   struct __htm_tdb *tdb = (struct __htm_tdb*)__tdb_ptr;
  316.  
  317.   return (tdb->format == 1
  318.           && (tdb->abort_code == 9 /* fetch conflict */
  319.               || tdb->abort_code == 10 /* store conflict */));
  320. }
  321.  
  322. static __inline long __attribute__((__always_inline__, __nodebug__))
  323. __TM_is_failure_persistent (long const __result)
  324. {
  325.   return __result == _HTM_TBEGIN_PERSISTENT;
  326. }
  327.  
  328. static __inline long __attribute__((__always_inline__, __nodebug__))
  329. __TM_failure_address (void* const __tdb_ptr)
  330. {
  331.   struct __htm_tdb *tdb = (struct __htm_tdb*)__tdb_ptr;
  332.   return tdb->atia;
  333. }
  334.  
  335. static __inline long __attribute__((__always_inline__, __nodebug__))
  336. __TM_failure_code (void* const __tdb_ptr)
  337. {
  338.   struct __htm_tdb *tdb = (struct __htm_tdb*)__tdb_ptr;
  339.  
  340.   return tdb->abort_code;
  341. }
  342.  
  343. #endif /* __s390__ */
  344.  
  345. #endif /* __HTMXLINTRIN_H  */
  346.