/* XL compiler hardware transactional execution intrinsics
   Copyright (C) 2013-2021 Free Software Foundation, Inc.
   Contributed by Andreas Krebbel (Andreas.Krebbel@de.ibm.com)

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#ifndef _HTMXLINTRIN_H
#define _HTMXLINTRIN_H

#include <stdint.h>

#include <htmintrin.h>

#ifdef __cplusplus
extern "C" {
#endif

/* These intrinsics are being made available for compatibility with
   the IBM XL compiler.  For documentation please see the "z/OS XL
   C/C++ Programming Guide" publicly available on the web.  */

/* FIXME: __TM_simple_begin and __TM_begin should be marked
   __always_inline__ as well but this currently produces an error
   since the tbegin builtins are "returns_twice" and setjmp_call_p
   (calls.c) therefore identifies the functions as calling setjmp.
   The tree inliner currently refuses to inline functions calling
   setjmp.  */

long
__TM_simple_begin ()
{
  return __builtin_tbegin_nofloat (0);
}

long
__TM_begin (void* const tdb)
{
  return __builtin_tbegin_nofloat (tdb);
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_end ()
{
  return __builtin_tend ();
}

extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_abort ()
{
  return __builtin_tabort (_HTM_FIRST_USER_ABORT_CODE);
}

extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_named_abort (unsigned char const code)
{
  return __builtin_tabort ((int)_HTM_FIRST_USER_ABORT_CODE + code);
}

extern __inline void __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_non_transactional_store (void* const addr, long long const value)
{
  __builtin_non_tx_store ((uint64_t*)addr, (uint64_t)value);
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_nesting_depth (void* const tdb_ptr)
{
  int depth = __builtin_tx_nesting_depth ();
  struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;

  if (depth != 0)
    return depth;

  if (tdb->format != 1)
    return 0;
  return tdb->nesting_depth;
}

/* Transaction failure diagnostics */

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_user_abort (void* const tdb_ptr)
{
  struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;

  if (tdb->format != 1)
    return 0;

  return !!(tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE);
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_named_user_abort (void* const tdb_ptr, unsigned char* code)
{
  struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;

  if (tdb->format != 1)
    return 0;

  if (tdb->abort_code >= _HTM_FIRST_USER_ABORT_CODE)
    {
      *code = tdb->abort_code - _HTM_FIRST_USER_ABORT_CODE;
      return 1;
    }
  return 0;
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_illegal (void* const tdb_ptr)
{
  struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;

  return (tdb->format == 1
	  && (tdb->abort_code == 4 /* unfiltered program interruption */
	      || tdb->abort_code == 11 /* restricted instruction */));
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_footprint_exceeded (void* const tdb_ptr)
{
  struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;

  return (tdb->format == 1
	  && (tdb->abort_code == 7 /* fetch overflow */
	      || tdb->abort_code == 8 /* store overflow */));
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_nested_too_deep (void* const tdb_ptr)
{
  struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;

  return tdb->format == 1 && tdb->abort_code == 13; /* depth exceeded */
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_conflict (void* const tdb_ptr)
{
  struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;

  return (tdb->format == 1
	  && (tdb->abort_code == 9 /* fetch conflict */
	      || tdb->abort_code == 10 /* store conflict */));
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_is_failure_persistent (long const result)
{
  return result == _HTM_TBEGIN_PERSISTENT;
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_failure_address (void* const tdb_ptr)
{
  struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;
#ifdef __s390x__
  return tdb->atia;
#else
  return tdb->atia & 0xffffffff;
#endif
}

extern __inline long __attribute__((__gnu_inline__, __always_inline__, __artificial__))
__TM_failure_code (void* const tdb_ptr)
{
  struct __htm_tdb *tdb = (struct __htm_tdb*)tdb_ptr;

  return tdb->abort_code;
}

#ifdef __cplusplus
}
#endif

#endif /* _HTMXLINTRIN_H */
