10b57cec5SDimitry Andric /*===---- htmintrin.h - Standard header for PowerPC HTM ---------------===*\
20b57cec5SDimitry Andric *
30b57cec5SDimitry Andric * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
40b57cec5SDimitry Andric * See https://llvm.org/LICENSE.txt for license information.
50b57cec5SDimitry Andric * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
60b57cec5SDimitry Andric *
70b57cec5SDimitry Andric \*===----------------------------------------------------------------------===*/
80b57cec5SDimitry Andric
90b57cec5SDimitry Andric #ifndef __HTMINTRIN_H
100b57cec5SDimitry Andric #define __HTMINTRIN_H
110b57cec5SDimitry Andric
120b57cec5SDimitry Andric #ifndef __HTM__
130b57cec5SDimitry Andric #error "HTM instruction set not enabled"
140b57cec5SDimitry Andric #endif
150b57cec5SDimitry Andric
160b57cec5SDimitry Andric #ifdef __powerpc__
170b57cec5SDimitry Andric
180b57cec5SDimitry Andric #include <stdint.h>
190b57cec5SDimitry Andric
200b57cec5SDimitry Andric typedef uint64_t texasr_t;
210b57cec5SDimitry Andric typedef uint32_t texasru_t;
220b57cec5SDimitry Andric typedef uint32_t texasrl_t;
230b57cec5SDimitry Andric typedef uintptr_t tfiar_t;
240b57cec5SDimitry Andric typedef uintptr_t tfhar_t;
250b57cec5SDimitry Andric
260b57cec5SDimitry Andric #define _HTM_STATE(CR0) ((CR0 >> 1) & 0x3)
270b57cec5SDimitry Andric #define _HTM_NONTRANSACTIONAL 0x0
280b57cec5SDimitry Andric #define _HTM_SUSPENDED 0x1
290b57cec5SDimitry Andric #define _HTM_TRANSACTIONAL 0x2
300b57cec5SDimitry Andric
310b57cec5SDimitry Andric #define _TEXASR_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \
320b57cec5SDimitry Andric (((TEXASR) >> (63-(BITNUM))) & ((1<<(SIZE))-1))
330b57cec5SDimitry Andric #define _TEXASRU_EXTRACT_BITS(TEXASR,BITNUM,SIZE) \
340b57cec5SDimitry Andric (((TEXASR) >> (31-(BITNUM))) & ((1<<(SIZE))-1))
350b57cec5SDimitry Andric
360b57cec5SDimitry Andric #define _TEXASR_FAILURE_CODE(TEXASR) \
370b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 7, 8)
380b57cec5SDimitry Andric #define _TEXASRU_FAILURE_CODE(TEXASRU) \
390b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 8)
400b57cec5SDimitry Andric
410b57cec5SDimitry Andric #define _TEXASR_FAILURE_PERSISTENT(TEXASR) \
420b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 7, 1)
430b57cec5SDimitry Andric #define _TEXASRU_FAILURE_PERSISTENT(TEXASRU) \
440b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 7, 1)
450b57cec5SDimitry Andric
460b57cec5SDimitry Andric #define _TEXASR_DISALLOWED(TEXASR) \
470b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 8, 1)
480b57cec5SDimitry Andric #define _TEXASRU_DISALLOWED(TEXASRU) \
490b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 8, 1)
500b57cec5SDimitry Andric
510b57cec5SDimitry Andric #define _TEXASR_NESTING_OVERFLOW(TEXASR) \
520b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 9, 1)
530b57cec5SDimitry Andric #define _TEXASRU_NESTING_OVERFLOW(TEXASRU) \
540b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 9, 1)
550b57cec5SDimitry Andric
560b57cec5SDimitry Andric #define _TEXASR_FOOTPRINT_OVERFLOW(TEXASR) \
570b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 10, 1)
580b57cec5SDimitry Andric #define _TEXASRU_FOOTPRINT_OVERFLOW(TEXASRU) \
590b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 10, 1)
600b57cec5SDimitry Andric
610b57cec5SDimitry Andric #define _TEXASR_SELF_INDUCED_CONFLICT(TEXASR) \
620b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 11, 1)
630b57cec5SDimitry Andric #define _TEXASRU_SELF_INDUCED_CONFLICT(TEXASRU) \
640b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 11, 1)
650b57cec5SDimitry Andric
660b57cec5SDimitry Andric #define _TEXASR_NON_TRANSACTIONAL_CONFLICT(TEXASR) \
670b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 12, 1)
680b57cec5SDimitry Andric #define _TEXASRU_NON_TRANSACTIONAL_CONFLICT(TEXASRU) \
690b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 12, 1)
700b57cec5SDimitry Andric
710b57cec5SDimitry Andric #define _TEXASR_TRANSACTION_CONFLICT(TEXASR) \
720b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 13, 1)
730b57cec5SDimitry Andric #define _TEXASRU_TRANSACTION_CONFLICT(TEXASRU) \
740b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 13, 1)
750b57cec5SDimitry Andric
760b57cec5SDimitry Andric #define _TEXASR_TRANSLATION_INVALIDATION_CONFLICT(TEXASR) \
770b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 14, 1)
780b57cec5SDimitry Andric #define _TEXASRU_TRANSLATION_INVALIDATION_CONFLICT(TEXASRU) \
790b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 14, 1)
800b57cec5SDimitry Andric
810b57cec5SDimitry Andric #define _TEXASR_IMPLEMENTAION_SPECIFIC(TEXASR) \
820b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 15, 1)
830b57cec5SDimitry Andric #define _TEXASRU_IMPLEMENTAION_SPECIFIC(TEXASRU) \
840b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 15, 1)
850b57cec5SDimitry Andric
860b57cec5SDimitry Andric #define _TEXASR_INSTRUCTION_FETCH_CONFLICT(TEXASR) \
870b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 16, 1)
880b57cec5SDimitry Andric #define _TEXASRU_INSTRUCTION_FETCH_CONFLICT(TEXASRU) \
890b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 16, 1)
900b57cec5SDimitry Andric
910b57cec5SDimitry Andric #define _TEXASR_ABORT(TEXASR) \
920b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 31, 1)
930b57cec5SDimitry Andric #define _TEXASRU_ABORT(TEXASRU) \
940b57cec5SDimitry Andric _TEXASRU_EXTRACT_BITS(TEXASRU, 31, 1)
950b57cec5SDimitry Andric
960b57cec5SDimitry Andric
970b57cec5SDimitry Andric #define _TEXASR_SUSPENDED(TEXASR) \
980b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 32, 1)
990b57cec5SDimitry Andric
1000b57cec5SDimitry Andric #define _TEXASR_PRIVILEGE(TEXASR) \
1010b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 35, 2)
1020b57cec5SDimitry Andric
1030b57cec5SDimitry Andric #define _TEXASR_FAILURE_SUMMARY(TEXASR) \
1040b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 36, 1)
1050b57cec5SDimitry Andric
1060b57cec5SDimitry Andric #define _TEXASR_TFIAR_EXACT(TEXASR) \
1070b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 37, 1)
1080b57cec5SDimitry Andric
1090b57cec5SDimitry Andric #define _TEXASR_ROT(TEXASR) \
1100b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 38, 1)
1110b57cec5SDimitry Andric
1120b57cec5SDimitry Andric #define _TEXASR_TRANSACTION_LEVEL(TEXASR) \
1130b57cec5SDimitry Andric _TEXASR_EXTRACT_BITS(TEXASR, 63, 12)
1140b57cec5SDimitry Andric
1150b57cec5SDimitry Andric #endif /* __powerpc */
1160b57cec5SDimitry Andric
1170b57cec5SDimitry Andric #ifdef __s390__
1180b57cec5SDimitry Andric
1190b57cec5SDimitry Andric /* Condition codes generated by tbegin */
1200b57cec5SDimitry Andric #define _HTM_TBEGIN_STARTED 0
1210b57cec5SDimitry Andric #define _HTM_TBEGIN_INDETERMINATE 1
1220b57cec5SDimitry Andric #define _HTM_TBEGIN_TRANSIENT 2
1230b57cec5SDimitry Andric #define _HTM_TBEGIN_PERSISTENT 3
1240b57cec5SDimitry Andric
1250b57cec5SDimitry Andric /* The abort codes below this threshold are reserved for machine use. */
1260b57cec5SDimitry Andric #define _HTM_FIRST_USER_ABORT_CODE 256
1270b57cec5SDimitry Andric
1280b57cec5SDimitry Andric /* The transaction diagnostic block is it is defined in the Principles
1290b57cec5SDimitry Andric of Operation chapter 5-91. */
1300b57cec5SDimitry Andric
1310b57cec5SDimitry Andric struct __htm_tdb {
1320b57cec5SDimitry Andric unsigned char format; /* 0 */
1330b57cec5SDimitry Andric unsigned char flags;
1340b57cec5SDimitry Andric unsigned char reserved1[4];
1350b57cec5SDimitry Andric unsigned short nesting_depth;
1360b57cec5SDimitry Andric unsigned long long abort_code; /* 8 */
1370b57cec5SDimitry Andric unsigned long long conflict_token; /* 16 */
1380b57cec5SDimitry Andric unsigned long long atia; /* 24 */
1390b57cec5SDimitry Andric unsigned char eaid; /* 32 */
1400b57cec5SDimitry Andric unsigned char dxc;
1410b57cec5SDimitry Andric unsigned char reserved2[2];
1420b57cec5SDimitry Andric unsigned int program_int_id;
1430b57cec5SDimitry Andric unsigned long long exception_id; /* 40 */
1440b57cec5SDimitry Andric unsigned long long bea; /* 48 */
1450b57cec5SDimitry Andric unsigned char reserved3[72]; /* 56 */
1460b57cec5SDimitry Andric unsigned long long gprs[16]; /* 128 */
1470b57cec5SDimitry Andric } __attribute__((__packed__, __aligned__ (8)));
1480b57cec5SDimitry Andric
1490b57cec5SDimitry Andric
1500b57cec5SDimitry Andric /* Helper intrinsics to retry tbegin in case of transient failure. */
1510b57cec5SDimitry Andric
1520b57cec5SDimitry Andric static __inline int __attribute__((__always_inline__, __nodebug__))
__builtin_tbegin_retry_null(int __retry)1530b57cec5SDimitry Andric __builtin_tbegin_retry_null (int __retry)
1540b57cec5SDimitry Andric {
1550b57cec5SDimitry Andric int cc, i = 0;
1560b57cec5SDimitry Andric
1570b57cec5SDimitry Andric while ((cc = __builtin_tbegin(0)) == _HTM_TBEGIN_TRANSIENT
1580b57cec5SDimitry Andric && i++ < __retry)
1590b57cec5SDimitry Andric __builtin_tx_assist(i);
1600b57cec5SDimitry Andric
1610b57cec5SDimitry Andric return cc;
1620b57cec5SDimitry Andric }
1630b57cec5SDimitry Andric
1640b57cec5SDimitry Andric static __inline int __attribute__((__always_inline__, __nodebug__))
__builtin_tbegin_retry_tdb(void * __tdb,int __retry)1650b57cec5SDimitry Andric __builtin_tbegin_retry_tdb (void *__tdb, int __retry)
1660b57cec5SDimitry Andric {
1670b57cec5SDimitry Andric int cc, i = 0;
1680b57cec5SDimitry Andric
1690b57cec5SDimitry Andric while ((cc = __builtin_tbegin(__tdb)) == _HTM_TBEGIN_TRANSIENT
1700b57cec5SDimitry Andric && i++ < __retry)
1710b57cec5SDimitry Andric __builtin_tx_assist(i);
1720b57cec5SDimitry Andric
1730b57cec5SDimitry Andric return cc;
1740b57cec5SDimitry Andric }
1750b57cec5SDimitry Andric
1760b57cec5SDimitry Andric #define __builtin_tbegin_retry(tdb, retry) \
1770b57cec5SDimitry Andric (__builtin_constant_p(tdb == 0) && tdb == 0 ? \
1780b57cec5SDimitry Andric __builtin_tbegin_retry_null(retry) : \
1790b57cec5SDimitry Andric __builtin_tbegin_retry_tdb(tdb, retry))
1800b57cec5SDimitry Andric
1810b57cec5SDimitry Andric static __inline int __attribute__((__always_inline__, __nodebug__))
__builtin_tbegin_retry_nofloat_null(int __retry)1820b57cec5SDimitry Andric __builtin_tbegin_retry_nofloat_null (int __retry)
1830b57cec5SDimitry Andric {
1840b57cec5SDimitry Andric int cc, i = 0;
1850b57cec5SDimitry Andric
1860b57cec5SDimitry Andric while ((cc = __builtin_tbegin_nofloat(0)) == _HTM_TBEGIN_TRANSIENT
1870b57cec5SDimitry Andric && i++ < __retry)
1880b57cec5SDimitry Andric __builtin_tx_assist(i);
1890b57cec5SDimitry Andric
1900b57cec5SDimitry Andric return cc;
1910b57cec5SDimitry Andric }
1920b57cec5SDimitry Andric
1930b57cec5SDimitry Andric static __inline int __attribute__((__always_inline__, __nodebug__))
__builtin_tbegin_retry_nofloat_tdb(void * __tdb,int __retry)1940b57cec5SDimitry Andric __builtin_tbegin_retry_nofloat_tdb (void *__tdb, int __retry)
1950b57cec5SDimitry Andric {
1960b57cec5SDimitry Andric int cc, i = 0;
1970b57cec5SDimitry Andric
1980b57cec5SDimitry Andric while ((cc = __builtin_tbegin_nofloat(__tdb)) == _HTM_TBEGIN_TRANSIENT
1990b57cec5SDimitry Andric && i++ < __retry)
2000b57cec5SDimitry Andric __builtin_tx_assist(i);
2010b57cec5SDimitry Andric
2020b57cec5SDimitry Andric return cc;
2030b57cec5SDimitry Andric }
2040b57cec5SDimitry Andric
2050b57cec5SDimitry Andric #define __builtin_tbegin_retry_nofloat(tdb, retry) \
2060b57cec5SDimitry Andric (__builtin_constant_p(tdb == 0) && tdb == 0 ? \
2070b57cec5SDimitry Andric __builtin_tbegin_retry_nofloat_null(retry) : \
2080b57cec5SDimitry Andric __builtin_tbegin_retry_nofloat_tdb(tdb, retry))
2090b57cec5SDimitry Andric
2100b57cec5SDimitry Andric #endif /* __s390__ */
2110b57cec5SDimitry Andric
2120b57cec5SDimitry Andric #endif /* __HTMINTRIN_H */
213