1 /* XL compiler Hardware Transactional Memory (HTM) execution intrinsics.
2    Copyright (C) 2013-2018 Free Software Foundation, Inc.
3    Contributed by Peter Bergner <bergner@vnet.ibm.com>.
4 
5    This file 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 of the License, or (at your option)
8    any later version.
9 
10    This file is distributed in the hope that it will be useful, but WITHOUT
11    ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12    FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
13    for more details.
14 
15    Under Section 7 of GPL version 3, you are granted additional
16    permissions described in the GCC Runtime Library Exception, version
17    3.1, as published by the Free Software Foundation.
18 
19    You should have received a copy of the GNU General Public License and
20    a copy of the GCC Runtime Library Exception along with this program;
21    see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
22    <http://www.gnu.org/licenses/>.  */
23 
24 #ifndef __HTM__
25 # error "HTM instruction set not enabled"
26 #endif /* __HTM__ */
27 
28 #ifndef _HTMXLINTRIN_H
29 #define _HTMXLINTRIN_H
30 
31 #include <stdint.h>
32 #include <htmintrin.h>
33 
34 #ifdef __cplusplus
35 extern "C" {
36 #endif
37 
38 #define _TEXASR_PTR(TM_BUF) \
39   ((texasr_t *)((TM_BUF)+0))
40 #define _TEXASRU_PTR(TM_BUF) \
41   ((texasru_t *)((TM_BUF)+0))
42 #define _TEXASRL_PTR(TM_BUF) \
43   ((texasrl_t *)((TM_BUF)+4))
44 #define _TFIAR_PTR(TM_BUF) \
45   ((tfiar_t *)((TM_BUF)+8))
46 
47 typedef char TM_buff_type[16];
48 
49 /* Compatibility macro with s390.  This macro can be used to determine
50    whether a transaction was successfully started from the __TM_begin()
51    and __TM_simple_begin() intrinsic functions below.  */
52 #define _HTM_TBEGIN_STARTED     1
53 
54 extern __inline long
55 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_simple_begin(void)56 __TM_simple_begin (void)
57 {
58   if (__builtin_expect (__builtin_tbegin (0), 1))
59     return _HTM_TBEGIN_STARTED;
60   return 0;
61 }
62 
63 extern __inline long
64 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_begin(void * const TM_buff)65 __TM_begin (void* const TM_buff)
66 {
67   *_TEXASRL_PTR (TM_buff) = 0;
68   if (__builtin_expect (__builtin_tbegin (0), 1))
69     return _HTM_TBEGIN_STARTED;
70 #ifdef __powerpc64__
71   *_TEXASR_PTR (TM_buff) = __builtin_get_texasr ();
72 #else
73   *_TEXASRU_PTR (TM_buff) = __builtin_get_texasru ();
74   *_TEXASRL_PTR (TM_buff) = __builtin_get_texasr ();
75 #endif
76   *_TFIAR_PTR (TM_buff) = __builtin_get_tfiar ();
77   return 0;
78 }
79 
80 extern __inline long
81 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_end(void)82 __TM_end (void)
83 {
84   unsigned char status = _HTM_STATE (__builtin_tend (0));
85   if (__builtin_expect (status, _HTM_TRANSACTIONAL))
86     return 1;
87   return 0;
88 }
89 
90 extern __inline void
91 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_abort(void)92 __TM_abort (void)
93 {
94   __builtin_tabort (0);
95 }
96 
97 extern __inline void
98 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_named_abort(unsigned char const code)99 __TM_named_abort (unsigned char const code)
100 {
101   __builtin_tabort (code);
102 }
103 
104 extern __inline void
105 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_resume(void)106 __TM_resume (void)
107 {
108   __builtin_tresume ();
109 }
110 
111 extern __inline void
112 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_suspend(void)113 __TM_suspend (void)
114 {
115   __builtin_tsuspend ();
116 }
117 
118 extern __inline long
119 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_user_abort(void * const TM_buff)120 __TM_is_user_abort (void* const TM_buff)
121 {
122   texasru_t texasru = *_TEXASRU_PTR (TM_buff);
123   return _TEXASRU_ABORT (texasru);
124 }
125 
126 extern __inline long
127 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_named_user_abort(void * const TM_buff,unsigned char * code)128 __TM_is_named_user_abort (void* const TM_buff, unsigned char *code)
129 {
130   texasru_t texasru = *_TEXASRU_PTR (TM_buff);
131 
132   *code = _TEXASRU_FAILURE_CODE (texasru);
133   return _TEXASRU_ABORT (texasru);
134 }
135 
136 extern __inline long
137 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_illegal(void * const TM_buff)138 __TM_is_illegal (void* const TM_buff)
139 {
140   texasru_t texasru = *_TEXASRU_PTR (TM_buff);
141   return _TEXASRU_DISALLOWED (texasru);
142 }
143 
144 extern __inline long
145 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_footprint_exceeded(void * const TM_buff)146 __TM_is_footprint_exceeded (void* const TM_buff)
147 {
148   texasru_t texasru = *_TEXASRU_PTR (TM_buff);
149   return _TEXASRU_FOOTPRINT_OVERFLOW (texasru);
150 }
151 
152 extern __inline long
153 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_nesting_depth(void * const TM_buff)154 __TM_nesting_depth (void* const TM_buff)
155 {
156   texasrl_t texasrl;
157 
158   if (_HTM_STATE (__builtin_ttest ()) == _HTM_NONTRANSACTIONAL)
159     {
160       texasrl = *_TEXASRL_PTR (TM_buff);
161       if (!_TEXASR_FAILURE_SUMMARY (texasrl))
162         texasrl = 0;
163     }
164   else
165     texasrl = (texasrl_t) __builtin_get_texasr ();
166 
167   return _TEXASR_TRANSACTION_LEVEL (texasrl);
168 }
169 
170 extern __inline long
171 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_nested_too_deep(void * const TM_buff)172 __TM_is_nested_too_deep(void* const TM_buff)
173 {
174   texasru_t texasru = *_TEXASRU_PTR (TM_buff);
175   return _TEXASRU_NESTING_OVERFLOW (texasru);
176 }
177 
178 extern __inline long
179 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_conflict(void * const TM_buff)180 __TM_is_conflict(void* const TM_buff)
181 {
182   texasru_t texasru = *_TEXASRU_PTR (TM_buff);
183   /* Return TEXASR bits 11 (Self-Induced Conflict) through
184      14 (Translation Invalidation Conflict).  */
185   return (_TEXASRU_EXTRACT_BITS (texasru, 14, 4)) ? 1 : 0;
186 }
187 
188 extern __inline long
189 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_failure_persistent(void * const TM_buff)190 __TM_is_failure_persistent(void* const TM_buff)
191 {
192   texasru_t texasru = *_TEXASRU_PTR (TM_buff);
193   return _TEXASRU_FAILURE_PERSISTENT (texasru);
194 }
195 
196 extern __inline long
197 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_failure_address(void * const TM_buff)198 __TM_failure_address(void* const TM_buff)
199 {
200   return *_TFIAR_PTR (TM_buff);
201 }
202 
203 extern __inline long long
204 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__TM_failure_code(void * const TM_buff)205 __TM_failure_code(void* const TM_buff)
206 {
207   return *_TEXASR_PTR (TM_buff);
208 }
209 
210 #ifdef __cplusplus
211 }
212 #endif
213 
214 #endif /* _HTMXLINTRIN_H */
215