core/stdarch/crates/core_arch/src/loongarch64/
mod.rs

1//! `LoongArch` intrinsics
2
3mod lasx;
4mod lsx;
5
6#[unstable(feature = "stdarch_loongarch", issue = "117427")]
7pub use self::lasx::*;
8#[unstable(feature = "stdarch_loongarch", issue = "117427")]
9pub use self::lsx::*;
10
11use crate::arch::asm;
12
13/// Reads the 64-bit stable counter value and the counter ID
14#[inline]
15#[unstable(feature = "stdarch_loongarch", issue = "117427")]
16pub unsafe fn rdtime_d() -> (i64, isize) {
17    let val: i64;
18    let tid: isize;
19    asm!("rdtime.d {}, {}", out(reg) val, out(reg) tid, options(readonly, nostack));
20    (val, tid)
21}
22
23/// Reads the lower 32-bit stable counter value and the counter ID
24#[inline]
25#[unstable(feature = "stdarch_loongarch", issue = "117427")]
26pub unsafe fn rdtimel_w() -> (i32, isize) {
27    let val: i32;
28    let tid: isize;
29    asm!("rdtimel.w {}, {}", out(reg) val, out(reg) tid, options(readonly, nostack));
30    (val, tid)
31}
32
33/// Reads the upper 32-bit stable counter value and the counter ID
34#[inline]
35#[unstable(feature = "stdarch_loongarch", issue = "117427")]
36pub unsafe fn rdtimeh_w() -> (i32, isize) {
37    let val: i32;
38    let tid: isize;
39    asm!("rdtimeh.w {}, {}", out(reg) val, out(reg) tid, options(readonly, nostack));
40    (val, tid)
41}
42
43#[allow(improper_ctypes)]
44unsafe extern "unadjusted" {
45    #[link_name = "llvm.loongarch.crc.w.b.w"]
46    fn __crc_w_b_w(a: i32, b: i32) -> i32;
47    #[link_name = "llvm.loongarch.crc.w.h.w"]
48    fn __crc_w_h_w(a: i32, b: i32) -> i32;
49    #[link_name = "llvm.loongarch.crc.w.w.w"]
50    fn __crc_w_w_w(a: i32, b: i32) -> i32;
51    #[link_name = "llvm.loongarch.crc.w.d.w"]
52    fn __crc_w_d_w(a: i64, b: i32) -> i32;
53    #[link_name = "llvm.loongarch.crcc.w.b.w"]
54    fn __crcc_w_b_w(a: i32, b: i32) -> i32;
55    #[link_name = "llvm.loongarch.crcc.w.h.w"]
56    fn __crcc_w_h_w(a: i32, b: i32) -> i32;
57    #[link_name = "llvm.loongarch.crcc.w.w.w"]
58    fn __crcc_w_w_w(a: i32, b: i32) -> i32;
59    #[link_name = "llvm.loongarch.crcc.w.d.w"]
60    fn __crcc_w_d_w(a: i64, b: i32) -> i32;
61    #[link_name = "llvm.loongarch.cacop.d"]
62    fn __cacop(a: i64, b: i64, c: i64);
63    #[link_name = "llvm.loongarch.dbar"]
64    fn __dbar(a: i32);
65    #[link_name = "llvm.loongarch.ibar"]
66    fn __ibar(a: i32);
67    #[link_name = "llvm.loongarch.movgr2fcsr"]
68    fn __movgr2fcsr(a: i32, b: i32);
69    #[link_name = "llvm.loongarch.movfcsr2gr"]
70    fn __movfcsr2gr(a: i32) -> i32;
71    #[link_name = "llvm.loongarch.csrrd.d"]
72    fn __csrrd(a: i32) -> i64;
73    #[link_name = "llvm.loongarch.csrwr.d"]
74    fn __csrwr(a: i64, b: i32) -> i64;
75    #[link_name = "llvm.loongarch.csrxchg.d"]
76    fn __csrxchg(a: i64, b: i64, c: i32) -> i64;
77    #[link_name = "llvm.loongarch.iocsrrd.b"]
78    fn __iocsrrd_b(a: i32) -> i32;
79    #[link_name = "llvm.loongarch.iocsrrd.h"]
80    fn __iocsrrd_h(a: i32) -> i32;
81    #[link_name = "llvm.loongarch.iocsrrd.w"]
82    fn __iocsrrd_w(a: i32) -> i32;
83    #[link_name = "llvm.loongarch.iocsrrd.d"]
84    fn __iocsrrd_d(a: i32) -> i64;
85    #[link_name = "llvm.loongarch.iocsrwr.b"]
86    fn __iocsrwr_b(a: i32, b: i32);
87    #[link_name = "llvm.loongarch.iocsrwr.h"]
88    fn __iocsrwr_h(a: i32, b: i32);
89    #[link_name = "llvm.loongarch.iocsrwr.w"]
90    fn __iocsrwr_w(a: i32, b: i32);
91    #[link_name = "llvm.loongarch.iocsrwr.d"]
92    fn __iocsrwr_d(a: i64, b: i32);
93    #[link_name = "llvm.loongarch.break"]
94    fn __break(a: i32);
95    #[link_name = "llvm.loongarch.cpucfg"]
96    fn __cpucfg(a: i32) -> i32;
97    #[link_name = "llvm.loongarch.syscall"]
98    fn __syscall(a: i32);
99    #[link_name = "llvm.loongarch.asrtle.d"]
100    fn __asrtle(a: i64, b: i64);
101    #[link_name = "llvm.loongarch.asrtgt.d"]
102    fn __asrtgt(a: i64, b: i64);
103    #[link_name = "llvm.loongarch.lddir.d"]
104    fn __lddir(a: i64, b: i64) -> i64;
105    #[link_name = "llvm.loongarch.ldpte.d"]
106    fn __ldpte(a: i64, b: i64);
107    #[link_name = "llvm.loongarch.frecipe.s"]
108    fn __frecipe_s(a: f32) -> f32;
109    #[link_name = "llvm.loongarch.frecipe.d"]
110    fn __frecipe_d(a: f64) -> f64;
111    #[link_name = "llvm.loongarch.frsqrte.s"]
112    fn __frsqrte_s(a: f32) -> f32;
113    #[link_name = "llvm.loongarch.frsqrte.d"]
114    fn __frsqrte_d(a: f64) -> f64;
115}
116
117/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
118#[inline]
119#[unstable(feature = "stdarch_loongarch", issue = "117427")]
120pub unsafe fn crc_w_b_w(a: i32, b: i32) -> i32 {
121    __crc_w_b_w(a, b)
122}
123
124/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
125#[inline]
126#[unstable(feature = "stdarch_loongarch", issue = "117427")]
127pub unsafe fn crc_w_h_w(a: i32, b: i32) -> i32 {
128    __crc_w_h_w(a, b)
129}
130
131/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
132#[inline]
133#[unstable(feature = "stdarch_loongarch", issue = "117427")]
134pub unsafe fn crc_w_w_w(a: i32, b: i32) -> i32 {
135    __crc_w_w_w(a, b)
136}
137
138/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
139#[inline]
140#[unstable(feature = "stdarch_loongarch", issue = "117427")]
141pub unsafe fn crc_w_d_w(a: i64, b: i32) -> i32 {
142    __crc_w_d_w(a, b)
143}
144
145/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
146#[inline]
147#[unstable(feature = "stdarch_loongarch", issue = "117427")]
148pub unsafe fn crcc_w_b_w(a: i32, b: i32) -> i32 {
149    __crcc_w_b_w(a, b)
150}
151
152/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
153#[inline]
154#[unstable(feature = "stdarch_loongarch", issue = "117427")]
155pub unsafe fn crcc_w_h_w(a: i32, b: i32) -> i32 {
156    __crcc_w_h_w(a, b)
157}
158
159/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
160#[inline]
161#[unstable(feature = "stdarch_loongarch", issue = "117427")]
162pub unsafe fn crcc_w_w_w(a: i32, b: i32) -> i32 {
163    __crcc_w_w_w(a, b)
164}
165
166/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
167#[inline]
168#[unstable(feature = "stdarch_loongarch", issue = "117427")]
169pub unsafe fn crcc_w_d_w(a: i64, b: i32) -> i32 {
170    __crcc_w_d_w(a, b)
171}
172
173/// Generates the cache operation instruction
174#[inline]
175#[unstable(feature = "stdarch_loongarch", issue = "117427")]
176pub unsafe fn cacop<const IMM12: i64>(a: i64, b: i64) {
177    static_assert_simm_bits!(IMM12, 12);
178    __cacop(a, b, IMM12);
179}
180
181/// Generates the memory barrier instruction
182#[inline]
183#[unstable(feature = "stdarch_loongarch", issue = "117427")]
184pub unsafe fn dbar<const IMM15: i32>() {
185    static_assert_uimm_bits!(IMM15, 15);
186    __dbar(IMM15);
187}
188
189/// Generates the instruction-fetch barrier instruction
190#[inline]
191#[unstable(feature = "stdarch_loongarch", issue = "117427")]
192pub unsafe fn ibar<const IMM15: i32>() {
193    static_assert_uimm_bits!(IMM15, 15);
194    __ibar(IMM15);
195}
196
197/// Moves data from a GPR to the FCSR
198#[inline]
199#[unstable(feature = "stdarch_loongarch", issue = "117427")]
200pub unsafe fn movgr2fcsr<const IMM5: i32>(a: i32) {
201    static_assert_uimm_bits!(IMM5, 5);
202    __movgr2fcsr(IMM5, a);
203}
204
205/// Moves data from a FCSR to the GPR
206#[inline]
207#[unstable(feature = "stdarch_loongarch", issue = "117427")]
208pub unsafe fn movfcsr2gr<const IMM5: i32>() -> i32 {
209    static_assert_uimm_bits!(IMM5, 5);
210    __movfcsr2gr(IMM5)
211}
212
213/// Reads the CSR
214#[inline]
215#[unstable(feature = "stdarch_loongarch", issue = "117427")]
216pub unsafe fn csrrd<const IMM14: i32>() -> i64 {
217    static_assert_uimm_bits!(IMM14, 14);
218    __csrrd(IMM14)
219}
220
221/// Writes the CSR
222#[inline]
223#[unstable(feature = "stdarch_loongarch", issue = "117427")]
224pub unsafe fn csrwr<const IMM14: i32>(a: i64) -> i64 {
225    static_assert_uimm_bits!(IMM14, 14);
226    __csrwr(a, IMM14)
227}
228
229/// Exchanges the CSR
230#[inline]
231#[unstable(feature = "stdarch_loongarch", issue = "117427")]
232pub unsafe fn csrxchg<const IMM14: i32>(a: i64, b: i64) -> i64 {
233    static_assert_uimm_bits!(IMM14, 14);
234    __csrxchg(a, b, IMM14)
235}
236
237/// Reads the 8-bit IO-CSR
238#[inline]
239#[unstable(feature = "stdarch_loongarch", issue = "117427")]
240pub unsafe fn iocsrrd_b(a: i32) -> i32 {
241    __iocsrrd_b(a)
242}
243
244/// Reads the 16-bit IO-CSR
245#[inline]
246#[unstable(feature = "stdarch_loongarch", issue = "117427")]
247pub unsafe fn iocsrrd_h(a: i32) -> i32 {
248    __iocsrrd_h(a)
249}
250
251/// Reads the 32-bit IO-CSR
252#[inline]
253#[unstable(feature = "stdarch_loongarch", issue = "117427")]
254pub unsafe fn iocsrrd_w(a: i32) -> i32 {
255    __iocsrrd_w(a)
256}
257
258/// Reads the 64-bit IO-CSR
259#[inline]
260#[unstable(feature = "stdarch_loongarch", issue = "117427")]
261pub unsafe fn iocsrrd_d(a: i32) -> i64 {
262    __iocsrrd_d(a)
263}
264
265/// Writes the 8-bit IO-CSR
266#[inline]
267#[unstable(feature = "stdarch_loongarch", issue = "117427")]
268pub unsafe fn iocsrwr_b(a: i32, b: i32) {
269    __iocsrwr_b(a, b)
270}
271
272/// Writes the 16-bit IO-CSR
273#[inline]
274#[unstable(feature = "stdarch_loongarch", issue = "117427")]
275pub unsafe fn iocsrwr_h(a: i32, b: i32) {
276    __iocsrwr_h(a, b)
277}
278
279/// Writes the 32-bit IO-CSR
280#[inline]
281#[unstable(feature = "stdarch_loongarch", issue = "117427")]
282pub unsafe fn iocsrwr_w(a: i32, b: i32) {
283    __iocsrwr_w(a, b)
284}
285
286/// Writes the 64-bit IO-CSR
287#[inline]
288#[unstable(feature = "stdarch_loongarch", issue = "117427")]
289pub unsafe fn iocsrwr_d(a: i64, b: i32) {
290    __iocsrwr_d(a, b)
291}
292
293/// Generates the breakpoint instruction
294#[inline]
295#[unstable(feature = "stdarch_loongarch", issue = "117427")]
296pub unsafe fn brk<const IMM15: i32>() {
297    static_assert_uimm_bits!(IMM15, 15);
298    __break(IMM15);
299}
300
301/// Reads the CPU configuration register
302#[inline]
303#[unstable(feature = "stdarch_loongarch", issue = "117427")]
304pub unsafe fn cpucfg(a: i32) -> i32 {
305    __cpucfg(a)
306}
307
308/// Generates the syscall instruction
309#[inline]
310#[unstable(feature = "stdarch_loongarch", issue = "117427")]
311pub unsafe fn syscall<const IMM15: i32>() {
312    static_assert_uimm_bits!(IMM15, 15);
313    __syscall(IMM15);
314}
315
316/// Generates the less-than-or-equal asseration instruction
317#[inline]
318#[unstable(feature = "stdarch_loongarch", issue = "117427")]
319pub unsafe fn asrtle(a: i64, b: i64) {
320    __asrtle(a, b);
321}
322
323/// Generates the greater-than asseration instruction
324#[inline]
325#[unstable(feature = "stdarch_loongarch", issue = "117427")]
326pub unsafe fn asrtgt(a: i64, b: i64) {
327    __asrtgt(a, b);
328}
329
330/// Loads the page table directory entry
331#[inline]
332#[unstable(feature = "stdarch_loongarch", issue = "117427")]
333pub unsafe fn lddir(a: i64, b: i64) -> i64 {
334    __lddir(a, b)
335}
336
337/// Loads the page table entry
338#[inline]
339#[unstable(feature = "stdarch_loongarch", issue = "117427")]
340pub unsafe fn ldpte(a: i64, b: i64) {
341    __ldpte(a, b)
342}
343
344/// Calculate the approximate single-precision result of 1.0 divided
345#[inline]
346#[target_feature(enable = "frecipe")]
347#[unstable(feature = "stdarch_loongarch", issue = "117427")]
348pub unsafe fn frecipe_s(a: f32) -> f32 {
349    __frecipe_s(a)
350}
351
352/// Calculate the approximate double-precision result of 1.0 divided
353#[inline]
354#[target_feature(enable = "frecipe")]
355#[unstable(feature = "stdarch_loongarch", issue = "117427")]
356pub unsafe fn frecipe_d(a: f64) -> f64 {
357    __frecipe_d(a)
358}
359
360/// Calculate the approximate single-precision result of dividing 1.0 by the square root
361#[inline]
362#[target_feature(enable = "frecipe")]
363#[unstable(feature = "stdarch_loongarch", issue = "117427")]
364pub unsafe fn frsqrte_s(a: f32) -> f32 {
365    __frsqrte_s(a)
366}
367
368/// Calculate the approximate double-precision result of dividing 1.0 by the square root
369#[inline]
370#[target_feature(enable = "frecipe")]
371#[unstable(feature = "stdarch_loongarch", issue = "117427")]
372pub unsafe fn frsqrte_d(a: f64) -> f64 {
373    __frsqrte_d(a)
374}