1*0b57cec5SDimitry Andric /*===---- lwpintrin.h - LWP intrinsics -------------------------------------===
2*0b57cec5SDimitry Andric *
3*0b57cec5SDimitry Andric * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*0b57cec5SDimitry Andric * See https://llvm.org/LICENSE.txt for license information.
5*0b57cec5SDimitry Andric * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*0b57cec5SDimitry Andric *
7*0b57cec5SDimitry Andric *===-----------------------------------------------------------------------===
8*0b57cec5SDimitry Andric */
9*0b57cec5SDimitry Andric
10*0b57cec5SDimitry Andric #ifndef __X86INTRIN_H
11*0b57cec5SDimitry Andric #error "Never use <lwpintrin.h> directly; include <x86intrin.h> instead."
12*0b57cec5SDimitry Andric #endif
13*0b57cec5SDimitry Andric
14*0b57cec5SDimitry Andric #ifndef __LWPINTRIN_H
15*0b57cec5SDimitry Andric #define __LWPINTRIN_H
16*0b57cec5SDimitry Andric
17*0b57cec5SDimitry Andric /* Define the default attributes for the functions in this file. */
18*0b57cec5SDimitry Andric #define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("lwp")))
19*0b57cec5SDimitry Andric
20*0b57cec5SDimitry Andric /// Parses the LWPCB at the specified address and enables
21*0b57cec5SDimitry Andric /// profiling if valid.
22*0b57cec5SDimitry Andric ///
23*0b57cec5SDimitry Andric /// \headerfile <x86intrin.h>
24*0b57cec5SDimitry Andric ///
25*0b57cec5SDimitry Andric /// This intrinsic corresponds to the <c> LLWPCB </c> instruction.
26*0b57cec5SDimitry Andric ///
27*0b57cec5SDimitry Andric /// \param __addr
28*0b57cec5SDimitry Andric /// Address to the new Lightweight Profiling Control Block (LWPCB). If the
29*0b57cec5SDimitry Andric /// LWPCB is valid, writes the address into the LWP_CBADDR MSR and enables
30*0b57cec5SDimitry Andric /// Lightweight Profiling.
31*0b57cec5SDimitry Andric static __inline__ void __DEFAULT_FN_ATTRS
__llwpcb(void * __addr)32*0b57cec5SDimitry Andric __llwpcb (void *__addr)
33*0b57cec5SDimitry Andric {
34*0b57cec5SDimitry Andric __builtin_ia32_llwpcb(__addr);
35*0b57cec5SDimitry Andric }
36*0b57cec5SDimitry Andric
37*0b57cec5SDimitry Andric /// Flushes the LWP state to memory and returns the address of the LWPCB.
38*0b57cec5SDimitry Andric ///
39*0b57cec5SDimitry Andric /// \headerfile <x86intrin.h>
40*0b57cec5SDimitry Andric ///
41*0b57cec5SDimitry Andric /// This intrinsic corresponds to the <c> SLWPCB </c> instruction.
42*0b57cec5SDimitry Andric ///
43*0b57cec5SDimitry Andric /// \return
44*0b57cec5SDimitry Andric /// Address to the current Lightweight Profiling Control Block (LWPCB).
45*0b57cec5SDimitry Andric /// If LWP is not currently enabled, returns NULL.
46*0b57cec5SDimitry Andric static __inline__ void* __DEFAULT_FN_ATTRS
__slwpcb(void)47*0b57cec5SDimitry Andric __slwpcb (void)
48*0b57cec5SDimitry Andric {
49*0b57cec5SDimitry Andric return __builtin_ia32_slwpcb();
50*0b57cec5SDimitry Andric }
51*0b57cec5SDimitry Andric
52*0b57cec5SDimitry Andric /// Inserts programmed event record into the LWP event ring buffer
53*0b57cec5SDimitry Andric /// and advances the ring buffer pointer.
54*0b57cec5SDimitry Andric ///
55*0b57cec5SDimitry Andric /// \headerfile <x86intrin.h>
56*0b57cec5SDimitry Andric ///
57*0b57cec5SDimitry Andric /// This intrinsic corresponds to the <c> LWPINS </c> instruction.
58*0b57cec5SDimitry Andric ///
59*0b57cec5SDimitry Andric /// \param DATA2
60*0b57cec5SDimitry Andric /// A 32-bit value is zero-extended and inserted into the 64-bit Data2 field.
61*0b57cec5SDimitry Andric /// \param DATA1
62*0b57cec5SDimitry Andric /// A 32-bit value is inserted into the 32-bit Data1 field.
63*0b57cec5SDimitry Andric /// \param FLAGS
64*0b57cec5SDimitry Andric /// A 32-bit immediate value is inserted into the 32-bit Flags field.
65*0b57cec5SDimitry Andric /// \returns If the ring buffer is full and LWP is running in Synchronized Mode,
66*0b57cec5SDimitry Andric /// the event record overwrites the last record in the buffer, the MissedEvents
67*0b57cec5SDimitry Andric /// counter in the LWPCB is incremented, the head pointer is not advanced, and
68*0b57cec5SDimitry Andric /// 1 is returned. Otherwise 0 is returned.
69*0b57cec5SDimitry Andric #define __lwpins32(DATA2, DATA1, FLAGS) \
70*0b57cec5SDimitry Andric (__builtin_ia32_lwpins32((unsigned int) (DATA2), (unsigned int) (DATA1), \
71*0b57cec5SDimitry Andric (unsigned int) (FLAGS)))
72*0b57cec5SDimitry Andric
73*0b57cec5SDimitry Andric /// Decrements the LWP programmed value sample event counter. If the result is
74*0b57cec5SDimitry Andric /// negative, inserts an event record into the LWP event ring buffer in memory
75*0b57cec5SDimitry Andric /// and advances the ring buffer pointer.
76*0b57cec5SDimitry Andric ///
77*0b57cec5SDimitry Andric /// \headerfile <x86intrin.h>
78*0b57cec5SDimitry Andric ///
79*0b57cec5SDimitry Andric /// This intrinsic corresponds to the <c> LWPVAL </c> instruction.
80*0b57cec5SDimitry Andric ///
81*0b57cec5SDimitry Andric /// \param DATA2
82*0b57cec5SDimitry Andric /// A 32-bit value is zero-extended and inserted into the 64-bit Data2 field.
83*0b57cec5SDimitry Andric /// \param DATA1
84*0b57cec5SDimitry Andric /// A 32-bit value is inserted into the 32-bit Data1 field.
85*0b57cec5SDimitry Andric /// \param FLAGS
86*0b57cec5SDimitry Andric /// A 32-bit immediate value is inserted into the 32-bit Flags field.
87*0b57cec5SDimitry Andric #define __lwpval32(DATA2, DATA1, FLAGS) \
88*0b57cec5SDimitry Andric (__builtin_ia32_lwpval32((unsigned int) (DATA2), (unsigned int) (DATA1), \
89*0b57cec5SDimitry Andric (unsigned int) (FLAGS)))
90*0b57cec5SDimitry Andric
91*0b57cec5SDimitry Andric #ifdef __x86_64__
92*0b57cec5SDimitry Andric
93*0b57cec5SDimitry Andric /// Inserts programmed event record into the LWP event ring buffer
94*0b57cec5SDimitry Andric /// and advances the ring buffer pointer.
95*0b57cec5SDimitry Andric ///
96*0b57cec5SDimitry Andric /// \headerfile <x86intrin.h>
97*0b57cec5SDimitry Andric ///
98*0b57cec5SDimitry Andric /// This intrinsic corresponds to the <c> LWPINS </c> instruction.
99*0b57cec5SDimitry Andric ///
100*0b57cec5SDimitry Andric /// \param DATA2
101*0b57cec5SDimitry Andric /// A 64-bit value is inserted into the 64-bit Data2 field.
102*0b57cec5SDimitry Andric /// \param DATA1
103*0b57cec5SDimitry Andric /// A 32-bit value is inserted into the 32-bit Data1 field.
104*0b57cec5SDimitry Andric /// \param FLAGS
105*0b57cec5SDimitry Andric /// A 32-bit immediate value is inserted into the 32-bit Flags field.
106*0b57cec5SDimitry Andric /// \returns If the ring buffer is full and LWP is running in Synchronized Mode,
107*0b57cec5SDimitry Andric /// the event record overwrites the last record in the buffer, the MissedEvents
108*0b57cec5SDimitry Andric /// counter in the LWPCB is incremented, the head pointer is not advanced, and
109*0b57cec5SDimitry Andric /// 1 is returned. Otherwise 0 is returned.
110*0b57cec5SDimitry Andric #define __lwpins64(DATA2, DATA1, FLAGS) \
111*0b57cec5SDimitry Andric (__builtin_ia32_lwpins64((unsigned long long) (DATA2), (unsigned int) (DATA1), \
112*0b57cec5SDimitry Andric (unsigned int) (FLAGS)))
113*0b57cec5SDimitry Andric
114*0b57cec5SDimitry Andric /// Decrements the LWP programmed value sample event counter. If the result is
115*0b57cec5SDimitry Andric /// negative, inserts an event record into the LWP event ring buffer in memory
116*0b57cec5SDimitry Andric /// and advances the ring buffer pointer.
117*0b57cec5SDimitry Andric ///
118*0b57cec5SDimitry Andric /// \headerfile <x86intrin.h>
119*0b57cec5SDimitry Andric ///
120*0b57cec5SDimitry Andric /// This intrinsic corresponds to the <c> LWPVAL </c> instruction.
121*0b57cec5SDimitry Andric ///
122*0b57cec5SDimitry Andric /// \param DATA2
123*0b57cec5SDimitry Andric /// A 64-bit value is and inserted into the 64-bit Data2 field.
124*0b57cec5SDimitry Andric /// \param DATA1
125*0b57cec5SDimitry Andric /// A 32-bit value is inserted into the 32-bit Data1 field.
126*0b57cec5SDimitry Andric /// \param FLAGS
127*0b57cec5SDimitry Andric /// A 32-bit immediate value is inserted into the 32-bit Flags field.
128*0b57cec5SDimitry Andric #define __lwpval64(DATA2, DATA1, FLAGS) \
129*0b57cec5SDimitry Andric (__builtin_ia32_lwpval64((unsigned long long) (DATA2), (unsigned int) (DATA1), \
130*0b57cec5SDimitry Andric (unsigned int) (FLAGS)))
131*0b57cec5SDimitry Andric
132*0b57cec5SDimitry Andric #endif
133*0b57cec5SDimitry Andric
134*0b57cec5SDimitry Andric #undef __DEFAULT_FN_ATTRS
135*0b57cec5SDimitry Andric
136*0b57cec5SDimitry Andric #endif /* __LWPINTRIN_H */
137