Skip to content

Commit

Permalink
Add loongarch64 support
Browse files Browse the repository at this point in the history
  • Loading branch information
yzewei committed Jul 6, 2024
1 parent 5662b1f commit 0c1dc59
Show file tree
Hide file tree
Showing 15 changed files with 327 additions and 17 deletions.
4 changes: 2 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ once_cell = { version = "1.5.2", optional = true }
# addition to the libc backend. The linux_raw backend is used by default. The
# libc backend can be selected via adding `--cfg=rustix_use_libc` to
# `RUSTFLAGS` or enabling the `use-libc` cargo feature.
[target.'cfg(all(not(rustix_use_libc), not(miri), target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "riscv64", all(rustix_use_experimental_asm, target_arch = "powerpc64"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"))))'.dependencies]
[target.'cfg(all(not(rustix_use_libc), not(miri), target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "riscv64", all(rustix_use_experimental_asm, target_arch = "powerpc64"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"), target_arch="loongarch64")))'.dependencies]
linux-raw-sys = { version = "0.4.14", default-features = false, features = ["general", "errno", "ioctl", "no_std", "elf"] }
libc_errno = { package = "errno", version = "0.3.8", default-features = false, optional = true }
libc = { version = "0.2.153", default-features = false, optional = true }
Expand All @@ -44,7 +44,7 @@ libc = { version = "0.2.153", default-features = false, optional = true }
#
# On all other Unix-family platforms, and under Miri, we always use the libc
# backend, so enable its dependencies unconditionally.
[target.'cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "riscv64", all(rustix_use_experimental_asm, target_arch = "powerpc64"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64")))))))'.dependencies]
[target.'cfg(all(not(windows), any(rustix_use_libc, miri, not(all(target_os = "linux", target_endian = "little", any(target_arch = "arm", all(target_arch = "aarch64", target_pointer_width = "64"), target_arch = "riscv64", all(rustix_use_experimental_asm, target_arch = "powerpc64"), all(rustix_use_experimental_asm, target_arch = "mips"), all(rustix_use_experimental_asm, target_arch = "mips32r6"), all(rustix_use_experimental_asm, target_arch = "mips64"), all(rustix_use_experimental_asm, target_arch = "mips64r6"), target_arch = "x86", all(target_arch = "x86_64", target_pointer_width = "64"), target_arch = "loongarch64"))))))'.dependencies]
libc_errno = { package = "errno", version = "0.3.8", default-features = false }
libc = { version = "0.2.153", default-features = false }

Expand Down
265 changes: 265 additions & 0 deletions src/backend/linux_raw/arch/loongarch64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,265 @@
//! loongarch64 Linux system calls.
use crate::backend::reg::{
ArgReg, FromAsm, RetReg, SyscallNumber, ToAsm, A0, A1, A2, A3, A4, A5, R0,
};
use core::arch::asm;

#[inline]
pub(in crate::backend) unsafe fn syscall0_readonly(nr: SyscallNumber<'_>) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
lateout("$a0") r0,
options(nostack, preserves_flags, readonly)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall1(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
options(nostack, preserves_flags)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall1_readonly(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
options(nostack, preserves_flags, readonly)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall1_noreturn(nr: SyscallNumber<'_>, a0: ArgReg<'_, A0>) -> ! {
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
in("$a0") a0.to_asm(),
options(noreturn)
);
}

#[inline]
pub(in crate::backend) unsafe fn syscall2(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
options(nostack, preserves_flags)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall2_readonly(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
options(nostack, preserves_flags, readonly)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall3(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
a2: ArgReg<'_, A2>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
in("$a2") a2.to_asm(),
options(nostack, preserves_flags)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall3_readonly(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
a2: ArgReg<'_, A2>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
in("$a2") a2.to_asm(),
options(nostack, preserves_flags, readonly)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall4(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
a2: ArgReg<'_, A2>,
a3: ArgReg<'_, A3>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
in("$a2") a2.to_asm(),
in("$a3") a3.to_asm(),
options(nostack, preserves_flags)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall4_readonly(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
a2: ArgReg<'_, A2>,
a3: ArgReg<'_, A3>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
in("$a2") a2.to_asm(),
in("$a3") a3.to_asm(),
options(nostack, preserves_flags, readonly)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall5(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
a2: ArgReg<'_, A2>,
a3: ArgReg<'_, A3>,
a4: ArgReg<'_, A4>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
in("$a2") a2.to_asm(),
in("$a3") a3.to_asm(),
in("$a4") a4.to_asm(),
options(nostack, preserves_flags)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall5_readonly(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
a2: ArgReg<'_, A2>,
a3: ArgReg<'_, A3>,
a4: ArgReg<'_, A4>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
in("$a2") a2.to_asm(),
in("$a3") a3.to_asm(),
in("$a4") a4.to_asm(),
options(nostack, preserves_flags, readonly)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall6(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
a2: ArgReg<'_, A2>,
a3: ArgReg<'_, A3>,
a4: ArgReg<'_, A4>,
a5: ArgReg<'_, A5>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
in("$a2") a2.to_asm(),
in("$a3") a3.to_asm(),
in("$a4") a4.to_asm(),
in("$a5") a5.to_asm(),
options(nostack, preserves_flags)
);
FromAsm::from_asm(r0)
}

#[inline]
pub(in crate::backend) unsafe fn syscall6_readonly(
nr: SyscallNumber<'_>,
a0: ArgReg<'_, A0>,
a1: ArgReg<'_, A1>,
a2: ArgReg<'_, A2>,
a3: ArgReg<'_, A3>,
a4: ArgReg<'_, A4>,
a5: ArgReg<'_, A5>,
) -> RetReg<R0> {
let r0;
asm!(
"syscall 0",
in("$a7") nr.to_asm(),
inlateout("$a0") a0.to_asm() => r0,
in("$a1") a1.to_asm(),
in("$a2") a2.to_asm(),
in("$a3") a3.to_asm(),
in("$a4") a4.to_asm(),
in("$a5") a5.to_asm(),
options(nostack, preserves_flags, readonly)
);
FromAsm::from_asm(r0)
}
1 change: 1 addition & 0 deletions src/backend/linux_raw/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@ pub(in crate::backend) mod asm;
#[cfg(any(
target_arch = "arm",
target_arch = "aarch64",
target_arch = "loongarch64",
target_arch = "mips",
target_arch = "mips32r6",
target_arch = "mips64",
Expand Down
6 changes: 5 additions & 1 deletion src/backend/linux_raw/conv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -235,7 +235,11 @@ pub(super) fn opt_mut<T: Sized, Num: ArgNumber>(t: Option<&mut T>) -> ArgReg<'_,

/// Convert an optional immutable reference into a `usize` for passing to a
/// syscall.
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
#[cfg(any(
target_arch = "aarch64",
target_arch = "loongarch64",
target_arch = "riscv64"
))]
#[inline]
pub(super) fn opt_ref<T: Sized, Num: ArgNumber>(t: Option<&T>) -> ArgReg<'_, Num> {
// This optimizes into the equivalent of `transmute(t)`, and has the
Expand Down
7 changes: 4 additions & 3 deletions src/backend/linux_raw/fs/dir.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
use crate::fd::{AsFd, BorrowedFd, OwnedFd};
use crate::ffi::{CStr, CString};
use crate::fs::{
fcntl_getfl, fstat, fstatfs, fstatvfs, openat, FileType, Mode, OFlags, Stat, StatFs, StatVfs,
};
use crate::fs::{fcntl_getfl, fstatfs, fstatvfs, openat, FileType, Mode, OFlags, StatFs, StatVfs};
#[cfg(not(target_arch = "loongarch64"))]
use crate::fs::{fstat, Stat};
use crate::io;
#[cfg(feature = "process")]
use crate::process::fchdir;
Expand Down Expand Up @@ -215,6 +215,7 @@ impl Dir {
}

/// `fstat(self)`
#[cfg(not(target_arch = "loongarch64"))]
#[inline]
pub fn stat(&self) -> io::Result<Stat> {
fstat(&self.fd)
Expand Down
Loading

0 comments on commit 0c1dc59

Please sign in to comment.