comparison gcc/config/s390/htmxlintrin.h @ 111:04ced10e8804

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