Skip to main content

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

1//! `LoongArch64` intrinsics
2
3mod lasx;
4mod lsx;
5mod simd;
6
7#[unstable(feature = "stdarch_loongarch", issue = "117427")]
8pub use self::lasx::*;
9#[unstable(feature = "stdarch_loongarch", issue = "117427")]
10pub use self::lsx::*;
11
12use crate::arch::asm;
13
14/// Reads the 64-bit stable counter value and the counter ID
15#[inline(always)]
16#[unstable(feature = "stdarch_loongarch", issue = "117427")]
17pub fn rdtime_d() -> (i64, isize) {
18    let (val, tid): (i64, isize);
19    unsafe { asm!("rdtime.d {}, {}", out(reg) val, out(reg) tid, options(readonly, nostack)) };
20    (val, tid)
21}
22
23#[allow(improper_ctypes)]
24unsafe extern "unadjusted" {
25    #[link_name = "llvm.loongarch.crc.w.b.w"]
26    fn __crc_w_b_w(a: i32, b: i32) -> i32;
27    #[link_name = "llvm.loongarch.crc.w.h.w"]
28    fn __crc_w_h_w(a: i32, b: i32) -> i32;
29    #[link_name = "llvm.loongarch.crc.w.w.w"]
30    fn __crc_w_w_w(a: i32, b: i32) -> i32;
31    #[link_name = "llvm.loongarch.crc.w.d.w"]
32    fn __crc_w_d_w(a: i64, b: i32) -> i32;
33    #[link_name = "llvm.loongarch.crcc.w.b.w"]
34    fn __crcc_w_b_w(a: i32, b: i32) -> i32;
35    #[link_name = "llvm.loongarch.crcc.w.h.w"]
36    fn __crcc_w_h_w(a: i32, b: i32) -> i32;
37    #[link_name = "llvm.loongarch.crcc.w.w.w"]
38    fn __crcc_w_w_w(a: i32, b: i32) -> i32;
39    #[link_name = "llvm.loongarch.crcc.w.d.w"]
40    fn __crcc_w_d_w(a: i64, b: i32) -> i32;
41    #[link_name = "llvm.loongarch.cacop.d"]
42    fn __cacop(a: i64, b: i64, c: i64);
43    #[link_name = "llvm.loongarch.csrrd.d"]
44    fn __csrrd(a: i32) -> i64;
45    #[link_name = "llvm.loongarch.csrwr.d"]
46    fn __csrwr(a: i64, b: i32) -> i64;
47    #[link_name = "llvm.loongarch.csrxchg.d"]
48    fn __csrxchg(a: i64, b: i64, c: i32) -> i64;
49    #[link_name = "llvm.loongarch.iocsrrd.d"]
50    fn __iocsrrd_d(a: i32) -> i64;
51    #[link_name = "llvm.loongarch.iocsrwr.d"]
52    fn __iocsrwr_d(a: i64, b: i32);
53    #[link_name = "llvm.loongarch.asrtle.d"]
54    fn __asrtle(a: i64, b: i64);
55    #[link_name = "llvm.loongarch.asrtgt.d"]
56    fn __asrtgt(a: i64, b: i64);
57    #[link_name = "llvm.loongarch.lddir.d"]
58    fn __lddir(a: i64, b: i64) -> i64;
59    #[link_name = "llvm.loongarch.ldpte.d"]
60    fn __ldpte(a: i64, b: i64);
61}
62
63/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
64#[inline(always)]
65#[unstable(feature = "stdarch_loongarch", issue = "117427")]
66pub fn crc_w_b_w(a: i8, b: i32) -> i32 {
67    unsafe { __crc_w_b_w(a.cast_unsigned() as i32, b) }
68}
69
70/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
71#[inline(always)]
72#[unstable(feature = "stdarch_loongarch", issue = "117427")]
73pub fn crc_w_h_w(a: i16, b: i32) -> i32 {
74    unsafe { __crc_w_h_w(a.cast_unsigned() as i32, b) }
75}
76
77/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
78#[inline(always)]
79#[unstable(feature = "stdarch_loongarch", issue = "117427")]
80pub fn crc_w_w_w(a: i32, b: i32) -> i32 {
81    unsafe { __crc_w_w_w(a, b) }
82}
83
84/// Calculate the CRC value using the IEEE 802.3 polynomial (0xEDB88320)
85#[inline(always)]
86#[unstable(feature = "stdarch_loongarch", issue = "117427")]
87pub fn crc_w_d_w(a: i64, b: i32) -> i32 {
88    unsafe { __crc_w_d_w(a, b) }
89}
90
91/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
92#[inline(always)]
93#[unstable(feature = "stdarch_loongarch", issue = "117427")]
94pub fn crcc_w_b_w(a: i8, b: i32) -> i32 {
95    unsafe { __crcc_w_b_w(a.cast_unsigned() as i32, b) }
96}
97
98/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
99#[inline(always)]
100#[unstable(feature = "stdarch_loongarch", issue = "117427")]
101pub fn crcc_w_h_w(a: i16, b: i32) -> i32 {
102    unsafe { __crcc_w_h_w(a.cast_unsigned() as i32, b) }
103}
104
105/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
106#[inline(always)]
107#[unstable(feature = "stdarch_loongarch", issue = "117427")]
108pub fn crcc_w_w_w(a: i32, b: i32) -> i32 {
109    unsafe { __crcc_w_w_w(a, b) }
110}
111
112/// Calculate the CRC value using the Castagnoli polynomial (0x82F63B78)
113#[inline(always)]
114#[unstable(feature = "stdarch_loongarch", issue = "117427")]
115pub fn crcc_w_d_w(a: i64, b: i32) -> i32 {
116    unsafe { __crcc_w_d_w(a, b) }
117}
118
119/// Generates the cache operation instruction
120#[inline(always)]
121#[unstable(feature = "stdarch_loongarch", issue = "117427")]
122pub unsafe fn cacop<const IMM5: i64, const IMM_S12: i64>(b: i64) {
123    static_assert_uimm_bits!(IMM5, 5);
124    static_assert_simm_bits!(IMM_S12, 12);
125    __cacop(IMM5, b, IMM_S12);
126}
127
128/// Reads the CSR
129#[inline(always)]
130#[unstable(feature = "stdarch_loongarch", issue = "117427")]
131pub unsafe fn csrrd<const IMM14: i32>() -> i64 {
132    static_assert_uimm_bits!(IMM14, 14);
133    __csrrd(IMM14)
134}
135
136/// Writes the CSR
137#[inline(always)]
138#[unstable(feature = "stdarch_loongarch", issue = "117427")]
139pub unsafe fn csrwr<const IMM14: i32>(a: i64) -> i64 {
140    static_assert_uimm_bits!(IMM14, 14);
141    __csrwr(a, IMM14)
142}
143
144/// Exchanges the CSR
145#[inline(always)]
146#[unstable(feature = "stdarch_loongarch", issue = "117427")]
147pub unsafe fn csrxchg<const IMM14: i32>(a: i64, b: i64) -> i64 {
148    static_assert_uimm_bits!(IMM14, 14);
149    __csrxchg(a, b, IMM14)
150}
151
152/// Reads the 64-bit IO-CSR
153#[inline(always)]
154#[unstable(feature = "stdarch_loongarch", issue = "117427")]
155pub unsafe fn iocsrrd_d(a: i32) -> i64 {
156    __iocsrrd_d(a)
157}
158
159/// Writes the 64-bit IO-CSR
160#[inline(always)]
161#[unstable(feature = "stdarch_loongarch", issue = "117427")]
162pub unsafe fn iocsrwr_d(a: i64, b: i32) {
163    __iocsrwr_d(a, b)
164}
165
166/// Generates the less-than-or-equal assertion instruction
167#[inline(always)]
168#[unstable(feature = "stdarch_loongarch", issue = "117427")]
169pub unsafe fn asrtle(a: i64, b: i64) {
170    __asrtle(a, b);
171}
172
173/// Generates the greater-than assertion instruction
174#[inline(always)]
175#[unstable(feature = "stdarch_loongarch", issue = "117427")]
176pub unsafe fn asrtgt(a: i64, b: i64) {
177    __asrtgt(a, b);
178}
179
180/// Loads the page table directory entry
181#[inline(always)]
182#[rustc_legacy_const_generics(1)]
183#[unstable(feature = "stdarch_loongarch", issue = "117427")]
184pub unsafe fn lddir<const IMM8: i64>(a: i64) -> i64 {
185    static_assert_uimm_bits!(IMM8, 8);
186    __lddir(a, IMM8)
187}
188
189/// Loads the page table entry
190#[inline(always)]
191#[rustc_legacy_const_generics(1)]
192#[unstable(feature = "stdarch_loongarch", issue = "117427")]
193pub unsafe fn ldpte<const IMM8: i64>(a: i64) {
194    static_assert_uimm_bits!(IMM8, 8);
195    __ldpte(a, IMM8)
196}
197
198#[cfg(test)]
199mod tests {
200    use super::*;
201
202    #[test]
203    fn crc32() {
204        assert_eq!(crc_w_b_w(-1, -1), 16777215);
205        assert_eq!(crc_w_h_w(-1, -1), 65535);
206        assert_eq!(crc_w_w_w(-1, -1), 0);
207        assert_eq!(crc_w_d_w(-1, -1), 3736805603u32.cast_signed());
208
209        assert_eq!(crcc_w_b_w(-1, -1), 16777215);
210        assert_eq!(crcc_w_h_w(-1, -1), 65535);
211        assert_eq!(crcc_w_w_w(-1, -1), 0);
212        assert_eq!(crcc_w_d_w(-1, -1), 3080238136u32.cast_signed());
213    }
214}