1317951Sdim/*===---- lwpintrin.h - LWP intrinsics -------------------------------------===
2317951Sdim *
3353358Sdim * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4353358Sdim * See https://llvm.org/LICENSE.txt for license information.
5353358Sdim * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6317951Sdim *
7317951Sdim *===-----------------------------------------------------------------------===
8317951Sdim */
9317951Sdim
10317951Sdim#ifndef __X86INTRIN_H
11317951Sdim#error "Never use <lwpintrin.h> directly; include <x86intrin.h> instead."
12317951Sdim#endif
13317951Sdim
14317951Sdim#ifndef __LWPINTRIN_H
15317951Sdim#define __LWPINTRIN_H
16317951Sdim
17317951Sdim/* Define the default attributes for the functions in this file. */
18317951Sdim#define __DEFAULT_FN_ATTRS __attribute__((__always_inline__, __nodebug__, __target__("lwp")))
19317951Sdim
20341825Sdim/// Parses the LWPCB at the specified address and enables
21317951Sdim///        profiling if valid.
22317951Sdim///
23317951Sdim/// \headerfile <x86intrin.h>
24317951Sdim///
25317951Sdim/// This intrinsic corresponds to the <c> LLWPCB </c> instruction.
26317951Sdim///
27317951Sdim/// \param __addr
28317951Sdim///    Address to the new Lightweight Profiling Control Block (LWPCB). If the
29317951Sdim///    LWPCB is valid, writes the address into the LWP_CBADDR MSR and enables
30317951Sdim///    Lightweight Profiling.
31317951Sdimstatic __inline__ void __DEFAULT_FN_ATTRS
32317951Sdim__llwpcb (void *__addr)
33317951Sdim{
34317951Sdim  __builtin_ia32_llwpcb(__addr);
35317951Sdim}
36317951Sdim
37341825Sdim/// Flushes the LWP state to memory and returns the address of the LWPCB.
38317951Sdim///
39317951Sdim/// \headerfile <x86intrin.h>
40317951Sdim///
41317951Sdim/// This intrinsic corresponds to the <c> SLWPCB </c> instruction.
42317951Sdim///
43317951Sdim/// \return
44317951Sdim///    Address to the current Lightweight Profiling Control Block (LWPCB).
45317951Sdim///    If LWP is not currently enabled, returns NULL.
46317951Sdimstatic __inline__ void* __DEFAULT_FN_ATTRS
47341825Sdim__slwpcb (void)
48317951Sdim{
49317951Sdim  return __builtin_ia32_slwpcb();
50317951Sdim}
51317951Sdim
52341825Sdim/// Inserts programmed event record into the LWP event ring buffer
53317951Sdim///        and advances the ring buffer pointer.
54317951Sdim///
55317951Sdim/// \headerfile <x86intrin.h>
56317951Sdim///
57317951Sdim/// This intrinsic corresponds to the <c> LWPINS </c> instruction.
58317951Sdim///
59317951Sdim/// \param DATA2
60317951Sdim///    A 32-bit value is zero-extended and inserted into the 64-bit Data2 field.
61317951Sdim/// \param DATA1
62317951Sdim///    A 32-bit value is inserted into the 32-bit Data1 field.
63317951Sdim/// \param FLAGS
64317951Sdim///    A 32-bit immediate value is inserted into the 32-bit Flags field.
65317951Sdim/// \returns If the ring buffer is full and LWP is running in Synchronized Mode,
66317951Sdim///    the event record overwrites the last record in the buffer, the MissedEvents
67317951Sdim///    counter in the LWPCB is incremented, the head pointer is not advanced, and
68317951Sdim///    1 is returned. Otherwise 0 is returned.
69317951Sdim#define __lwpins32(DATA2, DATA1, FLAGS) \
70317951Sdim  (__builtin_ia32_lwpins32((unsigned int) (DATA2), (unsigned int) (DATA1), \
71317951Sdim                           (unsigned int) (FLAGS)))
72317951Sdim
73341825Sdim/// Decrements the LWP programmed value sample event counter. If the result is
74317951Sdim///        negative, inserts an event record into the LWP event ring buffer in memory
75317951Sdim///        and advances the ring buffer pointer.
76317951Sdim///
77317951Sdim/// \headerfile <x86intrin.h>
78317951Sdim///
79317951Sdim/// This intrinsic corresponds to the <c> LWPVAL </c> instruction.
80317951Sdim///
81317951Sdim/// \param DATA2
82317951Sdim///    A 32-bit value is zero-extended and inserted into the 64-bit Data2 field.
83317951Sdim/// \param DATA1
84317951Sdim///    A 32-bit value is inserted into the 32-bit Data1 field.
85317951Sdim/// \param FLAGS
86317951Sdim///    A 32-bit immediate value is inserted into the 32-bit Flags field.
87317951Sdim#define __lwpval32(DATA2, DATA1, FLAGS) \
88317951Sdim  (__builtin_ia32_lwpval32((unsigned int) (DATA2), (unsigned int) (DATA1), \
89317951Sdim                           (unsigned int) (FLAGS)))
90317951Sdim
91317951Sdim#ifdef __x86_64__
92317951Sdim
93341825Sdim/// Inserts programmed event record into the LWP event ring buffer
94317951Sdim///        and advances the ring buffer pointer.
95317951Sdim///
96317951Sdim/// \headerfile <x86intrin.h>
97317951Sdim///
98317951Sdim/// This intrinsic corresponds to the <c> LWPINS </c> instruction.
99317951Sdim///
100317951Sdim/// \param DATA2
101317951Sdim///    A 64-bit value is inserted into the 64-bit Data2 field.
102317951Sdim/// \param DATA1
103317951Sdim///    A 32-bit value is inserted into the 32-bit Data1 field.
104317951Sdim/// \param FLAGS
105317951Sdim///    A 32-bit immediate value is inserted into the 32-bit Flags field.
106317951Sdim/// \returns If the ring buffer is full and LWP is running in Synchronized Mode,
107317951Sdim///    the event record overwrites the last record in the buffer, the MissedEvents
108317951Sdim///    counter in the LWPCB is incremented, the head pointer is not advanced, and
109317951Sdim///    1 is returned. Otherwise 0 is returned.
110317951Sdim#define __lwpins64(DATA2, DATA1, FLAGS) \
111317951Sdim  (__builtin_ia32_lwpins64((unsigned long long) (DATA2), (unsigned int) (DATA1), \
112317951Sdim                           (unsigned int) (FLAGS)))
113317951Sdim
114341825Sdim/// Decrements the LWP programmed value sample event counter. If the result is
115317951Sdim///        negative, inserts an event record into the LWP event ring buffer in memory
116317951Sdim///        and advances the ring buffer pointer.
117317951Sdim///
118317951Sdim/// \headerfile <x86intrin.h>
119317951Sdim///
120317951Sdim/// This intrinsic corresponds to the <c> LWPVAL </c> instruction.
121317951Sdim///
122317951Sdim/// \param DATA2
123317951Sdim///    A 64-bit value is and inserted into the 64-bit Data2 field.
124317951Sdim/// \param DATA1
125317951Sdim///    A 32-bit value is inserted into the 32-bit Data1 field.
126317951Sdim/// \param FLAGS
127317951Sdim///    A 32-bit immediate value is inserted into the 32-bit Flags field.
128317951Sdim#define __lwpval64(DATA2, DATA1, FLAGS) \
129317951Sdim  (__builtin_ia32_lwpval64((unsigned long long) (DATA2), (unsigned int) (DATA1), \
130317951Sdim                           (unsigned int) (FLAGS)))
131317951Sdim
132317951Sdim#endif
133317951Sdim
134317951Sdim#undef __DEFAULT_FN_ATTRS
135317951Sdim
136317951Sdim#endif /* __LWPINTRIN_H */
137