(root)/
gcc-13.2.0/
gcc/
config/
s390/
htmxlintrin.h
       1  /* XL compiler hardware transactional execution intrinsics
       2     Copyright (C) 2013-2023 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.cc) 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 */