1 /* SPDX-License-Identifier: BSD-3-Clause
2  * Copyright(c) 2012,2013 Intel Corporation
3  */
4 
5 #ifndef _RTE_RTM_H_
6 #define _RTE_RTM_H_ 1
7 
8 
9 /* Official RTM intrinsics interface matching gcc/icc, but works
10    on older gcc compatible compilers and binutils. */
11 
12 #include <rte_common.h>
13 
14 #ifdef __cplusplus
15 extern "C" {
16 #endif
17 
18 
19 #define RTE_XBEGIN_STARTED		(~0u)
20 #define RTE_XABORT_EXPLICIT		(1 << 0)
21 #define RTE_XABORT_RETRY		(1 << 1)
22 #define RTE_XABORT_CONFLICT		(1 << 2)
23 #define RTE_XABORT_CAPACITY		(1 << 3)
24 #define RTE_XABORT_DEBUG		(1 << 4)
25 #define RTE_XABORT_NESTED		(1 << 5)
26 #define RTE_XABORT_CODE(x)		(((x) >> 24) & 0xff)
27 
28 static __rte_always_inline
rte_xbegin(void)29 unsigned int rte_xbegin(void)
30 {
31 	unsigned int ret = RTE_XBEGIN_STARTED;
32 
33 	asm volatile(".byte 0xc7,0xf8 ; .long 0" : "+a" (ret) :: "memory");
34 	return ret;
35 }
36 
37 static __rte_always_inline
rte_xend(void)38 void rte_xend(void)
39 {
40 	 asm volatile(".byte 0x0f,0x01,0xd5" ::: "memory");
41 }
42 
43 /* not an inline function to workaround a clang bug with -O0 */
44 #define rte_xabort(status) do { \
45 	asm volatile(".byte 0xc6,0xf8,%P0" :: "i" (status) : "memory"); \
46 } while (0)
47 
48 static __rte_always_inline
rte_xtest(void)49 int rte_xtest(void)
50 {
51 	unsigned char out;
52 
53 	asm volatile(".byte 0x0f,0x01,0xd6 ; setnz %0" :
54 		"=r" (out) :: "memory");
55 	return out;
56 }
57 
58 #ifdef __cplusplus
59 }
60 #endif
61 
62 #endif /* _RTE_RTM_H_ */
63