zig

fork of https://codeberg.org/ziglang/zig
Log | Files | Refs | README | LICENSE

htmxlintrin.h (9225B) - Raw


      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  */