1 /*===------------ larchintrin.h - LoongArch intrinsics ---------------------===
2  *
3  * Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4  * See https://llvm.org/LICENSE.txt for license information.
5  * SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6  *
7  *===-----------------------------------------------------------------------===
8  */
9 
10 #ifndef _LOONGARCH_BASE_INTRIN_H
11 #define _LOONGARCH_BASE_INTRIN_H
12 
13 #ifdef __cplusplus
14 extern "C" {
15 #endif
16 
17 typedef struct rdtime {
18   unsigned int value;
19   unsigned int timeid;
20 } __rdtime_t;
21 
22 #if __loongarch_grlen == 64
23 typedef struct drdtime {
24   unsigned long dvalue;
25   unsigned long dtimeid;
26 } __drdtime_t;
27 
28 extern __inline __drdtime_t
29     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
30     __rdtime_d(void) {
31   __drdtime_t __drdtime;
32   __asm__ volatile(
33       "rdtime.d %[val], %[tid]\n\t"
34       : [val] "=&r"(__drdtime.dvalue), [tid] "=&r"(__drdtime.dtimeid));
35   return __drdtime;
36 }
37 #endif
38 
39 extern __inline __rdtime_t
40     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
41     __rdtimeh_w(void) {
42   __rdtime_t __rdtime;
43   __asm__ volatile("rdtimeh.w %[val], %[tid]\n\t"
44                    : [val] "=&r"(__rdtime.value), [tid] "=&r"(__rdtime.timeid));
45   return __rdtime;
46 }
47 
48 extern __inline __rdtime_t
49     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
50     __rdtimel_w(void) {
51   __rdtime_t __rdtime;
52   __asm__ volatile("rdtimel.w %[val], %[tid]\n\t"
53                    : [val] "=&r"(__rdtime.value), [tid] "=&r"(__rdtime.timeid));
54   return __rdtime;
55 }
56 
57 #if __loongarch_grlen == 64
58 extern __inline int
59     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
60     __crc_w_b_w(char _1, int _2) {
61   return (int)__builtin_loongarch_crc_w_b_w((char)_1, (int)_2);
62 }
63 
64 extern __inline int
65     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
66     __crc_w_h_w(short _1, int _2) {
67   return (int)__builtin_loongarch_crc_w_h_w((short)_1, (int)_2);
68 }
69 
70 extern __inline int
71     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
72     __crc_w_w_w(int _1, int _2) {
73   return (int)__builtin_loongarch_crc_w_w_w((int)_1, (int)_2);
74 }
75 
76 extern __inline int
77     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
78     __crc_w_d_w(long int _1, int _2) {
79   return (int)__builtin_loongarch_crc_w_d_w((long int)_1, (int)_2);
80 }
81 
82 extern __inline int
83     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
84     __crcc_w_b_w(char _1, int _2) {
85   return (int)__builtin_loongarch_crcc_w_b_w((char)_1, (int)_2);
86 }
87 
88 extern __inline int
89     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
90     __crcc_w_h_w(short _1, int _2) {
91   return (int)__builtin_loongarch_crcc_w_h_w((short)_1, (int)_2);
92 }
93 
94 extern __inline int
95     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
96     __crcc_w_w_w(int _1, int _2) {
97   return (int)__builtin_loongarch_crcc_w_w_w((int)_1, (int)_2);
98 }
99 
100 extern __inline int
101     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
102     __crcc_w_d_w(long int _1, int _2) {
103   return (int)__builtin_loongarch_crcc_w_d_w((long int)_1, (int)_2);
104 }
105 #endif
106 
107 #define __break(/*ui15*/ _1) __builtin_loongarch_break((_1))
108 
109 #if __loongarch_grlen == 32
110 #define __cacop_w(/*uimm5*/ _1, /*unsigned int*/ _2, /*simm12*/ _3)            \
111   ((void)__builtin_loongarch_cacop_w((_1), (unsigned int)(_2), (_3)))
112 #endif
113 
114 #if __loongarch_grlen == 64
115 #define __cacop_d(/*uimm5*/ _1, /*unsigned long int*/ _2, /*simm12*/ _3)       \
116   ((void)__builtin_loongarch_cacop_d((_1), (unsigned long int)(_2), (_3)))
117 #endif
118 
119 #define __dbar(/*ui15*/ _1) __builtin_loongarch_dbar((_1))
120 
121 #define __ibar(/*ui15*/ _1) __builtin_loongarch_ibar((_1))
122 
123 #define __movfcsr2gr(/*ui5*/ _1) __builtin_loongarch_movfcsr2gr((_1));
124 
125 #define __movgr2fcsr(/*ui5*/ _1, _2)                                           \
126   __builtin_loongarch_movgr2fcsr((_1), (unsigned int)_2);
127 
128 #define __syscall(/*ui15*/ _1) __builtin_loongarch_syscall((_1))
129 
130 #define __csrrd_w(/*ui14*/ _1) ((unsigned int)__builtin_loongarch_csrrd_w((_1)))
131 
132 #define __csrwr_w(/*unsigned int*/ _1, /*ui14*/ _2)                            \
133   ((unsigned int)__builtin_loongarch_csrwr_w((unsigned int)(_1), (_2)))
134 
135 #define __csrxchg_w(/*unsigned int*/ _1, /*unsigned int*/ _2, /*ui14*/ _3)     \
136   ((unsigned int)__builtin_loongarch_csrxchg_w((unsigned int)(_1),             \
137                                                (unsigned int)(_2), (_3)))
138 
139 #if __loongarch_grlen == 64
140 #define __csrrd_d(/*ui14*/ _1)                                                 \
141   ((unsigned long int)__builtin_loongarch_csrrd_d((_1)))
142 
143 #define __csrwr_d(/*unsigned long int*/ _1, /*ui14*/ _2)                       \
144   ((unsigned long int)__builtin_loongarch_csrwr_d((unsigned long int)(_1),     \
145                                                   (_2)))
146 
147 #define __csrxchg_d(/*unsigned long int*/ _1, /*unsigned long int*/ _2,        \
148                     /*ui14*/ _3)                                               \
149   ((unsigned long int)__builtin_loongarch_csrxchg_d(                           \
150       (unsigned long int)(_1), (unsigned long int)(_2), (_3)))
151 #endif
152 
153 extern __inline unsigned char
154     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
155     __iocsrrd_b(unsigned int _1) {
156   return (unsigned char)__builtin_loongarch_iocsrrd_b((unsigned int)_1);
157 }
158 
159 extern __inline unsigned char
160     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
161     __iocsrrd_h(unsigned int _1) {
162   return (unsigned short)__builtin_loongarch_iocsrrd_h((unsigned int)_1);
163 }
164 
165 extern __inline unsigned int
166     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
167     __iocsrrd_w(unsigned int _1) {
168   return (unsigned int)__builtin_loongarch_iocsrrd_w((unsigned int)_1);
169 }
170 
171 #if __loongarch_grlen == 64
172 extern __inline unsigned long int
173     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
174     __iocsrrd_d(unsigned int _1) {
175   return (unsigned long int)__builtin_loongarch_iocsrrd_d((unsigned int)_1);
176 }
177 #endif
178 
179 extern __inline void
180     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
181     __iocsrwr_b(unsigned char _1, unsigned int _2) {
182   __builtin_loongarch_iocsrwr_b((unsigned char)_1, (unsigned int)_2);
183 }
184 
185 extern __inline void
186     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
187     __iocsrwr_h(unsigned short _1, unsigned int _2) {
188   __builtin_loongarch_iocsrwr_h((unsigned short)_1, (unsigned int)_2);
189 }
190 
191 extern __inline void
192     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
193     __iocsrwr_w(unsigned int _1, unsigned int _2) {
194   __builtin_loongarch_iocsrwr_w((unsigned int)_1, (unsigned int)_2);
195 }
196 
197 extern __inline unsigned int
198     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
199     __cpucfg(unsigned int _1) {
200   return (unsigned int)__builtin_loongarch_cpucfg((unsigned int)_1);
201 }
202 
203 #if __loongarch_grlen == 64
204 extern __inline void
205     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
206     __iocsrwr_d(unsigned long int _1, unsigned int _2) {
207   __builtin_loongarch_iocsrwr_d((unsigned long int)_1, (unsigned int)_2);
208 }
209 
210 extern __inline void
211     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
212     __asrtgt_d(long int _1, long int _2) {
213   __builtin_loongarch_asrtgt_d((long int)_1, (long int)_2);
214 }
215 
216 extern __inline void
217     __attribute__((__gnu_inline__, __always_inline__, __artificial__))
218     __asrtle_d(long int _1, long int _2) {
219   __builtin_loongarch_asrtle_d((long int)_1, (long int)_2);
220 }
221 #endif
222 
223 #if __loongarch_grlen == 64
224 #define __lddir_d(/*long int*/ _1, /*ui5*/ _2)                                 \
225   ((long int)__builtin_loongarch_lddir_d((long int)(_1), (_2)))
226 
227 #define __ldpte_d(/*long int*/ _1, /*ui5*/ _2)                                 \
228   ((void)__builtin_loongarch_ldpte_d((long int)(_1), (_2)))
229 #endif
230 
231 #ifdef __cplusplus
232 }
233 #endif
234 #endif /* _LOONGARCH_BASE_INTRIN_H */
235