htmxlintrin.h 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. /* XL compiler hardware transactional execution intrinsics
  2. Copyright (C) 2013-2015 Free Software Foundation, Inc.
  3. Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)
  4. This file is part of GCC.
  5. GCC is free software; you can redistribute it and/or modify it under
  6. the terms of the GNU General Public License as published by the Free
  7. Software Foundation; either version 3, or (at your option) any later
  8. version.
  9. GCC is distributed in the hope that it will be useful, but WITHOUT ANY
  10. WARRANTY; without even the implied warranty of MERCHANTABILITY or
  11. FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
  12. for more details.
  13. You should have received a copy of the GNU General Public License
  14. along with GCC; see the file COPYING3. If not see
  15. <http://www.gnu.org/licenses/>. */
  16. #ifndef _HTMXLINTRIN_H
  17. #define _HTMXLINTRIN_H
  18. #include <stdint.h>
  19. #include <htmintrin.h>
  20. #ifdef __cplusplus
  21. extern "C" {
  22. #endif
  23. /* These intrinsics are being made available for compatibility with
  24. the IBM XL compiler. For documentation please see the "z/OS XL
  25. C/C++ Programming Guide" publicly available on the web. */
  26. /* FIXME: __TM_simple_begin and __TM_begin should be marked
  27. __always_inline__ as well but this currently produces an error
  28. since the tbegin builtins are "returns_twice" and setjmp_call_p
  29. (calls.c) therefore identifies the functions as calling setjmp.
  30. The tree inliner currently refuses to inline functions calling
  31. setjmp. */
  32. long
  33. __TM_simple_begin ()
  34. {
  35. return __builtin_tbegin_nofloat (0);
  36. }
  37. long
  38. __TM_begin (void* const tdb)
  39. {
  40. return __builtin_tbegin_nofloat (tdb);
  41. }
  42. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  43. __TM_end ()
  44. {
  45. return __builtin_tend ();
  46. }
  47. extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  48. __TM_abort ()
  49. {
  50. return __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE);
  51. }
  52. extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  53. __TM_named_abort (unsigned char const code)
  54. {
  55. return __builtin_tabort ((int)_HTM_FIRST_USER_ABORT_CODE + code);
  56. }
  57. extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  58. __TM_non_transactional_store (void* const addr, long long const value)
  59. {
  60. __builtin_non_tx_store ((uint64_t*)addr, (uint64_t)value);
  61. }
  62. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  63. __TM_nesting_depth (void* const tdb_ptr)
  64. {
  65. int depth = __builtin_tx_nesting_depth ();
  66. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  67. if (depth != 0)
  68. return depth;
  69. if (tdb->format != 1)
  70. return 0;
  71. return tdb->nesting_depth;
  72. }
  73. /* Transaction failure diagnostics */
  74. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  75. __TM_is_user_abort (void* const tdb_ptr)
  76. {
  77. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  78. if (tdb->format != 1)
  79. return 0;
  80. return !!(tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE);
  81. }
  82. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  83. __TM_is_named_user_abort (void* const tdb_ptr, unsigned char* code)
  84. {
  85. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  86. if (tdb->format != 1)
  87. return 0;
  88. if (tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE)
  89. {
  90. *code = tdb->abort_code - _HTM_FIRST_USER_ABORT_CODE;
  91. return 1;
  92. }
  93. return 0;
  94. }
  95. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  96. __TM_is_illegal (void* const tdb_ptr)
  97. {
  98. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  99. return (tdb->format == 1
  100. && (tdb->abort_code == 4 /* unfiltered program interruption */
  101. || tdb->abort_code == 11 /* restricted instruction */));
  102. }
  103. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  104. __TM_is_footprint_exceeded (void* const tdb_ptr)
  105. {
  106. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  107. return (tdb->format == 1
  108. && (tdb->abort_code == 7 /* fetch overflow */
  109. || tdb->abort_code == 8 /* store overflow */));
  110. }
  111. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  112. __TM_is_nested_too_deep (void* const tdb_ptr)
  113. {
  114. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  115. return tdb->format == 1 && tdb->abort_code == 13; /* depth exceeded */
  116. }
  117. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  118. __TM_is_conflict (void* const tdb_ptr)
  119. {
  120. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  121. return (tdb->format == 1
  122. && (tdb->abort_code == 9 /* fetch conflict */
  123. || tdb->abort_code == 10 /* store conflict */));
  124. }
  125. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  126. __TM_is_failure_persistent (long const result)
  127. {
  128. return result == _HTM_TBEGIN_PERSISTENT;
  129. }
  130. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  131. __TM_failure_address (void* const tdb_ptr)
  132. {
  133. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  134. #ifdef __s390x__
  135. return tdb->atia;
  136. #else
  137. return tdb->atia & 0xffffffff;
  138. #endif
  139. }
  140. extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
  141. __TM_failure_code (void* const tdb_ptr)
  142. {
  143. struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
  144. return tdb->abort_code;
  145. }
  146. #ifdef __cplusplus
  147. }
  148. #endif
  149. #endif /* _HTMXLINTRIN_H */