htmxlintrin.h 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363
  1. /*===---- htmxlintrin.h - XL compiler HTM execution intrinsics-------------===*\
  2. *
  3. * Permission is hereby granted, free of charge, to any person obtaining a copy
  4. * of this software and associated documentation files (the "Software"), to deal
  5. * in the Software without restriction, including without limitation the rights
  6. * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  7. * copies of the Software, and to permit persons to whom the Software is
  8. * furnished to do so, subject to the following conditions:
  9. *
  10. * The above copyright notice and this permission notice shall be included in
  11. * all copies or substantial portions of the Software.
  12. *
  13. * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  14. * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  15. * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  16. * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  17. * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  18. * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  19. * THE SOFTWARE.
  20. *
  21. \*===----------------------------------------------------------------------===*/
  22. #ifndef __HTMXLINTRIN_H
  23. #define __HTMXLINTRIN_H
  24. #ifndef __HTM__
  25. #error "HTM instruction set not enabled"
  26. #endif
  27. #include <htmintrin.h>
  28. #ifdef __powerpc__
  29. #ifdef __cplusplus
  30. extern "C" {
  31. #endif
  32. #define _TEXASR_PTR(TM_BUF) \
  33. ((texasr_t *)((TM_BUF)+0))
  34. #define _TEXASRU_PTR(TM_BUF) \
  35. ((texasru_t *)((TM_BUF)+0))
  36. #define _TEXASRL_PTR(TM_BUF) \
  37. ((texasrl_t *)((TM_BUF)+4))
  38. #define _TFIAR_PTR(TM_BUF) \
  39. ((tfiar_t *)((TM_BUF)+8))
  40. typedef char TM_buff_type[16];
  41. /* This macro can be used to determine whether a transaction was successfully
  42. started from the __TM_begin() and __TM_simple_begin() intrinsic functions
  43. below. */
  44. #define _HTM_TBEGIN_STARTED 1
  45. extern __inline long
  46. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  47. __TM_simple_begin (void)
  48. {
  49. if (__builtin_expect (__builtin_tbegin (0), 1))
  50. return _HTM_TBEGIN_STARTED;
  51. return 0;
  52. }
  53. extern __inline long
  54. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  55. __TM_begin (void* const TM_buff)
  56. {
  57. *_TEXASRL_PTR (TM_buff) = 0;
  58. if (__builtin_expect (__builtin_tbegin (0), 1))
  59. return _HTM_TBEGIN_STARTED;
  60. #ifdef __powerpc64__
  61. *_TEXASR_PTR (TM_buff) = __builtin_get_texasr ();
  62. #else
  63. *_TEXASRU_PTR (TM_buff) = __builtin_get_texasru ();
  64. *_TEXASRL_PTR (TM_buff) = __builtin_get_texasr ();
  65. #endif
  66. *_TFIAR_PTR (TM_buff) = __builtin_get_tfiar ();
  67. return 0;
  68. }
  69. extern __inline long
  70. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  71. __TM_end (void)
  72. {
  73. if (__builtin_expect (__builtin_tend (0), 1))
  74. return 1;
  75. return 0;
  76. }
  77. extern __inline void
  78. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  79. __TM_abort (void)
  80. {
  81. __builtin_tabort (0);
  82. }
  83. extern __inline void
  84. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  85. __TM_named_abort (unsigned char const code)
  86. {
  87. __builtin_tabort (code);
  88. }
  89. extern __inline void
  90. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  91. __TM_resume (void)
  92. {
  93. __builtin_tresume ();
  94. }
  95. extern __inline void
  96. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  97. __TM_suspend (void)
  98. {
  99. __builtin_tsuspend ();
  100. }
  101. extern __inline long
  102. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  103. __TM_is_user_abort (void* const TM_buff)
  104. {
  105. texasru_t texasru = *_TEXASRU_PTR (TM_buff);
  106. return _TEXASRU_ABORT (texasru);
  107. }
  108. extern __inline long
  109. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  110. __TM_is_named_user_abort (void* const TM_buff, unsigned char *code)
  111. {
  112. texasru_t texasru = *_TEXASRU_PTR (TM_buff);
  113. *code = _TEXASRU_FAILURE_CODE (texasru);
  114. return _TEXASRU_ABORT (texasru);
  115. }
  116. extern __inline long
  117. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  118. __TM_is_illegal (void* const TM_buff)
  119. {
  120. texasru_t texasru = *_TEXASRU_PTR (TM_buff);
  121. return _TEXASRU_DISALLOWED (texasru);
  122. }
  123. extern __inline long
  124. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  125. __TM_is_footprint_exceeded (void* const TM_buff)
  126. {
  127. texasru_t texasru = *_TEXASRU_PTR (TM_buff);
  128. return _TEXASRU_FOOTPRINT_OVERFLOW (texasru);
  129. }
  130. extern __inline long
  131. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  132. __TM_nesting_depth (void* const TM_buff)
  133. {
  134. texasrl_t texasrl;
  135. if (_HTM_STATE (__builtin_ttest ()) == _HTM_NONTRANSACTIONAL)
  136. {
  137. texasrl = *_TEXASRL_PTR (TM_buff);
  138. if (!_TEXASR_FAILURE_SUMMARY (texasrl))
  139. texasrl = 0;
  140. }
  141. else
  142. texasrl = (texasrl_t) __builtin_get_texasr ();
  143. return _TEXASR_TRANSACTION_LEVEL (texasrl);
  144. }
  145. extern __inline long
  146. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  147. __TM_is_nested_too_deep(void* const TM_buff)
  148. {
  149. texasru_t texasru = *_TEXASRU_PTR (TM_buff);
  150. return _TEXASRU_NESTING_OVERFLOW (texasru);
  151. }
  152. extern __inline long
  153. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  154. __TM_is_conflict(void* const TM_buff)
  155. {
  156. texasru_t texasru = *_TEXASRU_PTR (TM_buff);
  157. /* Return TEXASR bits 11 (Self-Induced Conflict) through
  158. 14 (Translation Invalidation Conflict). */
  159. return (_TEXASRU_EXTRACT_BITS (texasru, 14, 4)) ? 1 : 0;
  160. }
  161. extern __inline long
  162. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  163. __TM_is_failure_persistent(void* const TM_buff)
  164. {
  165. texasru_t texasru = *_TEXASRU_PTR (TM_buff);
  166. return _TEXASRU_FAILURE_PERSISTENT (texasru);
  167. }
  168. extern __inline long
  169. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  170. __TM_failure_address(void* const TM_buff)
  171. {
  172. return *_TFIAR_PTR (TM_buff);
  173. }
  174. extern __inline long long
  175. __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
  176. __TM_failure_code(void* const TM_buff)
  177. {
  178. return *_TEXASR_PTR (TM_buff);
  179. }
  180. #ifdef __cplusplus
  181. }
  182. #endif
  183. #endif /* __powerpc__ */
  184. #ifdef __s390__
  185. #include <stdint.h>
  186. /* These intrinsics are being made available for compatibility with
  187. the IBM XL compiler. For documentation please see the "z/OS XL
  188. C/C++ Programming Guide" publically available on the web. */
  189. static __inline long __attribute__((__always_inline__, __nodebug__))
  190. __TM_simple_begin ()
  191. {
  192. return __builtin_tbegin_nofloat (0);
  193. }
  194. static __inline long __attribute__((__always_inline__, __nodebug__))
  195. __TM_begin (void* const tdb)
  196. {
  197. return __builtin_tbegin_nofloat (tdb);
  198. }
  199. static __inline long __attribute__((__always_inline__, __nodebug__))
  200. __TM_end ()
  201. {
  202. return __builtin_tend ();
  203. }
  204. static __inline void __attribute__((__always_inline__))
  205. __TM_abort ()
  206. {
  207. return __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE);
  208. }
  209. static __inline void __attribute__((__always_inline__, __nodebug__))
  210. __TM_named_abort (unsigned char const code)
  211. {
  212. return __builtin_tabort ((int)_HTM_FIRST_USER_ABORT_CODE + code);
  213. }
  214. static __inline void __attribute__((__always_inline__, __nodebug__))
  215. __TM_non_transactional_store (void* const addr, long long const value)
  216. {
  217. __builtin_non_tx_store ((uint64_t*)addr, (uint64_t)value);
  218. }
  219. static __inline long __attribute__((__always_inline__, __nodebug__))
  220. __TM_nesting_depth (void* const tdb_ptr)
  221. {
  222. int depth = __builtin_tx_nesting_depth ();
  223. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  224. if (depth != 0)
  225. return depth;
  226. if (tdb->format != 1)
  227. return 0;
  228. return tdb->nesting_depth;
  229. }
  230. /* Transaction failure diagnostics */
  231. static __inline long __attribute__((__always_inline__, __nodebug__))
  232. __TM_is_user_abort (void* const tdb_ptr)
  233. {
  234. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  235. if (tdb->format != 1)
  236. return 0;
  237. return !!(tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE);
  238. }
  239. static __inline long __attribute__((__always_inline__, __nodebug__))
  240. __TM_is_named_user_abort (void* const tdb_ptr, unsigned char* code)
  241. {
  242. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  243. if (tdb->format != 1)
  244. return 0;
  245. if (tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE)
  246. {
  247. *code = tdb->abort_code - _HTM_FIRST_USER_ABORT_CODE;
  248. return 1;
  249. }
  250. return 0;
  251. }
  252. static __inline long __attribute__((__always_inline__, __nodebug__))
  253. __TM_is_illegal (void* const tdb_ptr)
  254. {
  255. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  256. return (tdb->format == 1
  257. && (tdb->abort_code == 4 /* unfiltered program interruption */
  258. || tdb->abort_code == 11 /* restricted instruction */));
  259. }
  260. static __inline long __attribute__((__always_inline__, __nodebug__))
  261. __TM_is_footprint_exceeded (void* const tdb_ptr)
  262. {
  263. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  264. return (tdb->format == 1
  265. && (tdb->abort_code == 7 /* fetch overflow */
  266. || tdb->abort_code == 8 /* store overflow */));
  267. }
  268. static __inline long __attribute__((__always_inline__, __nodebug__))
  269. __TM_is_nested_too_deep (void* const tdb_ptr)
  270. {
  271. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  272. return tdb->format == 1 && tdb->abort_code == 13; /* depth exceeded */
  273. }
  274. static __inline long __attribute__((__always_inline__, __nodebug__))
  275. __TM_is_conflict (void* const tdb_ptr)
  276. {
  277. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  278. return (tdb->format == 1
  279. && (tdb->abort_code == 9 /* fetch conflict */
  280. || tdb->abort_code == 10 /* store conflict */));
  281. }
  282. static __inline long __attribute__((__always_inline__, __nodebug__))
  283. __TM_is_failure_persistent (long const result)
  284. {
  285. return result == _HTM_TBEGIN_PERSISTENT;
  286. }
  287. static __inline long __attribute__((__always_inline__, __nodebug__))
  288. __TM_failure_address (void* const tdb_ptr)
  289. {
  290. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  291. return tdb->atia;
  292. }
  293. static __inline long __attribute__((__always_inline__, __nodebug__))
  294. __TM_failure_code (void* const tdb_ptr)
  295. {
  296. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  297. return tdb->abort_code;
  298. }
  299. #endif /* __s390__ */
  300. #endif /* __HTMXLINTRIN_H */