Subversion Repositories QNX 8.QNX8 LLVM/Clang compiler suite

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
14 pmbaty 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  */