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