1 /* Intrinsics for LoongArch BASE operations.
2 Copyright (C) 2021-2022 Free Software Foundation, Inc.
3 Contributed by Loongson Ltd.
4
5 This file is part of GCC.
6
7 GCC is free software; you can redistribute it and/or modify it
8 under the terms of the GNU General Public License as published
9 by the Free Software Foundation; either version 3, or (at your
10 option) any later version.
11
12 GCC is distributed in the hope that it will be useful, but WITHOUT
13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
14 or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public
15 License for more details.
16
17 Under Section 7 of GPL version 3, you are granted additional
18 permissions described in the GCC Runtime Library Exception, version
19 3.1, as published by the Free Software Foundation.
20
21 You should have received a copy of the GNU General Public License and
22 a copy of the GCC Runtime Library Exception along with this program;
23 see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
24 <http://www.gnu.org/licenses/>. */
25
26 #ifndef _GCC_LOONGARCH_BASE_INTRIN_H
27 #define _GCC_LOONGARCH_BASE_INTRIN_H
28
29 #ifdef __cplusplus
30 extern "C" {
31 #endif
32
33 typedef struct drdtime
34 {
35 unsigned long dvalue;
36 unsigned long dtimeid;
37 } __drdtime_t;
38
39 typedef struct rdtime
40 {
41 unsigned int value;
42 unsigned int timeid;
43 } __rdtime_t;
44
45 #ifdef __loongarch64
46 extern __inline __drdtime_t
47 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__rdtime_d(void)48 __rdtime_d (void)
49 {
50 __drdtime_t __drdtime;
51 __asm__ volatile (
52 "rdtime.d\t%[val],%[tid]\n\t"
53 : [val]"=&r"(__drdtime.dvalue),[tid]"=&r"(__drdtime.dtimeid)
54 :);
55 return __drdtime;
56 }
57 #endif
58
59 extern __inline __rdtime_t
60 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__rdtimeh_w(void)61 __rdtimeh_w (void)
62 {
63 __rdtime_t __rdtime;
64 __asm__ volatile (
65 "rdtimeh.w\t%[val],%[tid]\n\t"
66 : [val]"=&r"(__rdtime.value),[tid]"=&r"(__rdtime.timeid)
67 :);
68 return __rdtime;
69 }
70
71 extern __inline __rdtime_t
72 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__rdtimel_w(void)73 __rdtimel_w (void)
74 {
75 __rdtime_t __rdtime;
76 __asm__ volatile (
77 "rdtimel.w\t%[val],%[tid]\n\t"
78 : [val]"=&r"(__rdtime.value),[tid]"=&r"(__rdtime.timeid)
79 :);
80 return __rdtime;
81 }
82
83 /* Assembly instruction format: rj, fcsr. */
84 /* Data types in instruction templates: USI, UQI. */
85 #define __movfcsr2gr(/*ui5*/ _1) __builtin_loongarch_movfcsr2gr ((_1));
86
87 /* Assembly instruction format: fcsr, rj. */
88 /* Data types in instruction templates: VOID, UQI, USI. */
89 #define __movgr2fcsr(/*ui5*/ _1, _2) \
90 __builtin_loongarch_movgr2fcsr ((_1), (unsigned int) _2);
91
92 #if defined __loongarch64
93 /* Assembly instruction format: ui5, rj, si12. */
94 /* Data types in instruction templates: VOID, USI, UDI, SI. */
95 #define __cacop_d(/*ui5*/ _1, /*unsigned long int*/ _2, /*si12*/ _3) \
96 ((void) __builtin_loongarch_cacop_d ((_1), (unsigned long int) (_2), (_3)))
97 #else
98 #error "Unsupported ABI."
99 #endif
100
101 /* Assembly instruction format: rd, rj. */
102 /* Data types in instruction templates: USI, USI. */
103 extern __inline unsigned int
104 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__cpucfg(unsigned int _1)105 __cpucfg (unsigned int _1)
106 {
107 return (unsigned int) __builtin_loongarch_cpucfg ((unsigned int) _1);
108 }
109
110 #ifdef __loongarch64
111 /* Assembly instruction format: rj, rk. */
112 /* Data types in instruction templates: DI, DI. */
113 extern __inline void
114 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__asrtle_d(long int _1,long int _2)115 __asrtle_d (long int _1, long int _2)
116 {
117 __builtin_loongarch_asrtle_d ((long int) _1, (long int) _2);
118 }
119
120 /* Assembly instruction format: rj, rk. */
121 /* Data types in instruction templates: DI, DI. */
122 extern __inline void
123 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__asrtgt_d(long int _1,long int _2)124 __asrtgt_d (long int _1, long int _2)
125 {
126 __builtin_loongarch_asrtgt_d ((long int) _1, (long int) _2);
127 }
128 #endif
129
130 #if defined __loongarch64
131 /* Assembly instruction format: rd, rj, ui5. */
132 /* Data types in instruction templates: DI, DI, UQI. */
133 #define __lddir_d(/*long int*/ _1, /*ui5*/ _2) \
134 ((long int) __builtin_loongarch_lddir_d ((long int) (_1), (_2)))
135 #else
136 #error "Unsupported ABI."
137 #endif
138
139 #if defined __loongarch64
140 /* Assembly instruction format: rj, ui5. */
141 /* Data types in instruction templates: VOID, DI, UQI. */
142 #define __ldpte_d(/*long int*/ _1, /*ui5*/ _2) \
143 ((void) __builtin_loongarch_ldpte_d ((long int) (_1), (_2)))
144 #else
145 #error "Unsupported ABI."
146 #endif
147
148 /* Assembly instruction format: rd, rj, rk. */
149 /* Data types in instruction templates: SI, QI, SI. */
150 extern __inline int
151 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__crc_w_b_w(char _1,int _2)152 __crc_w_b_w (char _1, int _2)
153 {
154 return (int) __builtin_loongarch_crc_w_b_w ((char) _1, (int) _2);
155 }
156
157 /* Assembly instruction format: rd, rj, rk. */
158 /* Data types in instruction templates: SI, HI, SI. */
159 extern __inline int
160 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__crc_w_h_w(short _1,int _2)161 __crc_w_h_w (short _1, int _2)
162 {
163 return (int) __builtin_loongarch_crc_w_h_w ((short) _1, (int) _2);
164 }
165
166 /* Assembly instruction format: rd, rj, rk. */
167 /* Data types in instruction templates: SI, SI, SI. */
168 extern __inline int
169 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__crc_w_w_w(int _1,int _2)170 __crc_w_w_w (int _1, int _2)
171 {
172 return (int) __builtin_loongarch_crc_w_w_w ((int) _1, (int) _2);
173 }
174
175 #ifdef __loongarch64
176 /* Assembly instruction format: rd, rj, rk. */
177 /* Data types in instruction templates: SI, DI, SI. */
178 extern __inline int
179 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__crc_w_d_w(long int _1,int _2)180 __crc_w_d_w (long int _1, int _2)
181 {
182 return (int) __builtin_loongarch_crc_w_d_w ((long int) _1, (int) _2);
183 }
184 #endif
185
186 /* Assembly instruction format: rd, rj, rk. */
187 /* Data types in instruction templates: SI, QI, SI. */
188 extern __inline int
189 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__crcc_w_b_w(char _1,int _2)190 __crcc_w_b_w (char _1, int _2)
191 {
192 return (int) __builtin_loongarch_crcc_w_b_w ((char) _1, (int) _2);
193 }
194
195 /* Assembly instruction format: rd, rj, rk. */
196 /* Data types in instruction templates: SI, HI, SI. */
197 extern __inline int
198 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__crcc_w_h_w(short _1,int _2)199 __crcc_w_h_w (short _1, int _2)
200 {
201 return (int) __builtin_loongarch_crcc_w_h_w ((short) _1, (int) _2);
202 }
203
204 /* Assembly instruction format: rd, rj, rk. */
205 /* Data types in instruction templates: SI, SI, SI. */
206 extern __inline int
207 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__crcc_w_w_w(int _1,int _2)208 __crcc_w_w_w (int _1, int _2)
209 {
210 return (int) __builtin_loongarch_crcc_w_w_w ((int) _1, (int) _2);
211 }
212
213 #ifdef __loongarch64
214 /* Assembly instruction format: rd, rj, rk. */
215 /* Data types in instruction templates: SI, DI, SI. */
216 extern __inline int
217 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__crcc_w_d_w(long int _1,int _2)218 __crcc_w_d_w (long int _1, int _2)
219 {
220 return (int) __builtin_loongarch_crcc_w_d_w ((long int) _1, (int) _2);
221 }
222 #endif
223
224 /* Assembly instruction format: rd, ui14. */
225 /* Data types in instruction templates: USI, USI. */
226 #define __csrrd_w(/*ui14*/ _1) \
227 ((unsigned int) __builtin_loongarch_csrrd_w ((_1)))
228
229 /* Assembly instruction format: rd, ui14. */
230 /* Data types in instruction templates: USI, USI, USI. */
231 #define __csrwr_w(/*unsigned int*/ _1, /*ui14*/ _2) \
232 ((unsigned int) __builtin_loongarch_csrwr_w ((unsigned int) (_1), (_2)))
233
234 /* Assembly instruction format: rd, rj, ui14. */
235 /* Data types in instruction templates: USI, USI, USI, USI. */
236 #define __csrxchg_w(/*unsigned int*/ _1, /*unsigned int*/ _2, /*ui14*/ _3) \
237 ((unsigned int) __builtin_loongarch_csrxchg_w ((unsigned int) (_1), \
238 (unsigned int) (_2), (_3)))
239
240 #ifdef __loongarch64
241 /* Assembly instruction format: rd, ui14. */
242 /* Data types in instruction templates: UDI, USI. */
243 #define __csrrd_d(/*ui14*/ _1) \
244 ((unsigned long int) __builtin_loongarch_csrrd_d ((_1)))
245
246 /* Assembly instruction format: rd, ui14. */
247 /* Data types in instruction templates: UDI, UDI, USI. */
248 #define __csrwr_d(/*unsigned long int*/ _1, /*ui14*/ _2) \
249 ((unsigned long int) __builtin_loongarch_csrwr_d ((unsigned long int) (_1), \
250 (_2)))
251
252 /* Assembly instruction format: rd, rj, ui14. */
253 /* Data types in instruction templates: UDI, UDI, UDI, USI. */
254 #define __csrxchg_d(/*unsigned long int*/ _1, /*unsigned long int*/ _2, \
255 /*ui14*/ _3) \
256 ((unsigned long int) __builtin_loongarch_csrxchg_d ( \
257 (unsigned long int) (_1), (unsigned long int) (_2), (_3)))
258 #endif
259
260 /* Assembly instruction format: rd, rj. */
261 /* Data types in instruction templates: UQI, USI. */
262 extern __inline unsigned char
263 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__iocsrrd_b(unsigned int _1)264 __iocsrrd_b (unsigned int _1)
265 {
266 return (unsigned char) __builtin_loongarch_iocsrrd_b ((unsigned int) _1);
267 }
268
269 /* Assembly instruction format: rd, rj. */
270 /* Data types in instruction templates: UHI, USI. */
271 extern __inline unsigned char
272 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__iocsrrd_h(unsigned int _1)273 __iocsrrd_h (unsigned int _1)
274 {
275 return (unsigned short) __builtin_loongarch_iocsrrd_h ((unsigned int) _1);
276 }
277
278 /* Assembly instruction format: rd, rj. */
279 /* Data types in instruction templates: USI, USI. */
280 extern __inline unsigned int
281 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__iocsrrd_w(unsigned int _1)282 __iocsrrd_w (unsigned int _1)
283 {
284 return (unsigned int) __builtin_loongarch_iocsrrd_w ((unsigned int) _1);
285 }
286
287 #ifdef __loongarch64
288 /* Assembly instruction format: rd, rj. */
289 /* Data types in instruction templates: UDI, USI. */
290 extern __inline unsigned long int
291 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__iocsrrd_d(unsigned int _1)292 __iocsrrd_d (unsigned int _1)
293 {
294 return (unsigned long int) __builtin_loongarch_iocsrrd_d ((unsigned int) _1);
295 }
296 #endif
297
298 /* Assembly instruction format: rd, rj. */
299 /* Data types in instruction templates: VOID, UQI, USI. */
300 extern __inline void
301 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__iocsrwr_b(unsigned char _1,unsigned int _2)302 __iocsrwr_b (unsigned char _1, unsigned int _2)
303 {
304 __builtin_loongarch_iocsrwr_b ((unsigned char) _1, (unsigned int) _2);
305 }
306
307 /* Assembly instruction format: rd, rj. */
308 /* Data types in instruction templates: VOID, UHI, USI. */
309 extern __inline void
310 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__iocsrwr_h(unsigned short _1,unsigned int _2)311 __iocsrwr_h (unsigned short _1, unsigned int _2)
312 {
313 __builtin_loongarch_iocsrwr_h ((unsigned short) _1, (unsigned int) _2);
314 }
315
316 /* Assembly instruction format: rd, rj. */
317 /* Data types in instruction templates: VOID, USI, USI. */
318 extern __inline void
319 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__iocsrwr_w(unsigned int _1,unsigned int _2)320 __iocsrwr_w (unsigned int _1, unsigned int _2)
321 {
322 __builtin_loongarch_iocsrwr_w ((unsigned int) _1, (unsigned int) _2);
323 }
324
325 #ifdef __loongarch64
326 /* Assembly instruction format: rd, rj. */
327 /* Data types in instruction templates: VOID, UDI, USI. */
328 extern __inline void
329 __attribute__ ((__gnu_inline__, __always_inline__, __artificial__))
__iocsrwr_d(unsigned long int _1,unsigned int _2)330 __iocsrwr_d (unsigned long int _1, unsigned int _2)
331 {
332 __builtin_loongarch_iocsrwr_d ((unsigned long int) _1, (unsigned int) _2);
333 }
334 #endif
335
336 /* Assembly instruction format: ui15. */
337 /* Data types in instruction templates: USI. */
338 #define __dbar(/*ui15*/ _1) __builtin_loongarch_dbar ((_1))
339
340 /* Assembly instruction format: ui15. */
341 /* Data types in instruction templates: USI. */
342 #define __ibar(/*ui15*/ _1) __builtin_loongarch_ibar ((_1))
343
344 /* Assembly instruction format: ui15. */
345 /* Data types in instruction templates: USI. */
346 #define __syscall(/*ui15*/ _1) __builtin_loongarch_syscall ((_1))
347
348 /* Assembly instruction format: ui15. */
349 /* Data types in instruction templates: USI. */
350 #define __break(/*ui15*/ _1) __builtin_loongarch_break ((_1))
351
352 #ifdef __cplusplus
353 }
354 #endif
355 #endif /* _GCC_LOONGARCH_BASE_INTRIN_H */
356