Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add loongarch64 support #53

Merged
merged 5 commits into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ jobs:
- armv5te-unknown-linux-gnueabi
- armv7-linux-androideabi
- armv7-unknown-linux-gnueabi
# Does not work on cross-rs v0.2.5 release, waiting for the next one
# - loongarch64-unknown-linux-gnu
- thumbv7neon-linux-androideabi
- thumbv7neon-unknown-linux-gnueabihf
- aarch64-unknown-linux-gnu
Expand Down Expand Up @@ -93,6 +95,8 @@ jobs:
- armv5te-unknown-linux-gnueabi
- armv7-linux-androideabi
- armv7-unknown-linux-gnueabi
# Does not work on cross-rs v0.2.5 release, waiting for the next one
# - loongarch64-unknown-linux-gnu
- thumbv7neon-linux-androideabi
- thumbv7neon-unknown-linux-gnueabihf
#- mips-unknown-linux-gnu
Expand Down
5 changes: 3 additions & 2 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,14 @@ std = []

# Includes the syscall tables for all architectures.
all = [
"aarch64", "arm", "mips", "mips64", "powerpc", "powerpc64", "riscv32",
"riscv64", "s390x", "sparc", "sparc64", "x86", "x86_64"
"aarch64", "arm", "loongarch64", "mips", "mips64", "powerpc", "powerpc64",
"riscv32", "riscv64", "s390x", "sparc", "sparc64", "x86", "x86_64"
]

# Enable syscall tables for individual architectures.
aarch64 = []
arm = []
loongarch64 = []
mips = []
mips64 = []
powerpc = []
Expand Down
683 changes: 683 additions & 0 deletions src/arch/loongarch64.rs

Large diffs are not rendered by default.

5 changes: 5 additions & 0 deletions src/arch/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,8 @@ mod macros;
pub mod aarch64;
#[cfg(any(target_arch = "arm", feature = "arm"))]
pub mod arm;
#[cfg(any(target_arch = "loongarch64", feature = "loongarch64"))]
pub mod loongarch64;
#[cfg(any(target_arch = "mips", feature = "mips"))]
pub mod mips;
#[cfg(any(target_arch = "mips64", feature = "mips64"))]
Expand Down Expand Up @@ -34,6 +36,9 @@ pub use aarch64::*;
#[cfg(target_arch = "arm")]
pub use arm::*;

#[cfg(target_arch = "loongarch64")]
pub use loongarch64::*;

#[cfg(target_arch = "mips")]
pub use mips::*;

Expand Down
280 changes: 280 additions & 0 deletions src/syscall/loongarch64.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,280 @@
// LoongArch has the following registers:
//
// | General-purpose Register Convension |
// | ============================================================================== |
// | Symbolic Name | Number | Usage |
// | ============== | =============== | =========================================== |
// | zero | 0 | Constant 0 |
// | ra | 1 | Return address |
// | tp | 2 | Thread pointer |
// | sp | 3 | Stack pointer |
// | a0 - a1 | 4 - 5 | Argument registers / return value registers |
// | a2 - a7 | 6 - 11 | Argument registers |
// | t0 - t8 | 12 - 20 | Tempotaty registers |
// | u0 | 21 | Reserved |
// | fp | 22 | Frame pointer / Static register |
// | s0 - s8 | 23 - 31 | Static registers |
//
// | Floating-point Register Convention |
// | ============================================================================= |
// | Symbolic Name | Number | Usage |
// | ============= | =============== | =========================================== |
// | fa0 - fa1 | 0 - 1 | Argument registers / return value registers |
// | fa2 - fa7 | 2 - 7 | Argument registers |
// | ft0 - ft15 | 8 - 23 | Temporary registers |
// | fs0 - fs7 | 24 - 31 | Static registers |
//
// Note that v0, v1, fv0, fv1 are just old aliases to a0, a1, fa0, fa1 (not recommended to use)
//
// The following registers are used for args 1-7:
//
// arg1: %a0
// arg2: %a1
// arg3: %a2
// arg4: %a3
// arg5: %a4
// arg6: %a5
// arg7: %a6
//
// %a7 is the syscall number
// %a0, %a1 is the return value
// registers t0 - t8 should be clobbered

use core::arch::asm;

/// Issues a raw system call with 0 arguments.
///
/// # Safety
///
/// Running a system call is inherently unsafe. It is the caller's
/// responsibility to ensure safety.
#[inline]
pub unsafe fn syscall0(n: usize) -> usize {
let mut ret: usize;
asm!(
"syscall 0",
in("$a7") n,
lateout("$a0") ret,
// All temporary registers are always clobbered
lateout("$t0") _,
lateout("$t1") _,
lateout("$t2") _,
lateout("$t3") _,
lateout("$t4") _,
lateout("$t5") _,
lateout("$t6") _,
lateout("$t7") _,
lateout("$t8") _,
options(nostack, preserves_flags)
);
ret
}

/// Issues a raw system call with 1 argument.
///
/// # Safety
///
/// Running a system call is inherently unsafe. It is the caller's
/// responsibility to ensure safety.
#[inline]
pub unsafe fn syscall1(n: usize, arg1: usize) -> usize {
let mut ret: usize;
asm!(
"syscall 0",
in("$a7") n,
inlateout("$a0") arg1 => ret,
// All temporary registers are always clobbered
lateout("$t0") _,
lateout("$t1") _,
lateout("$t2") _,
lateout("$t3") _,
lateout("$t4") _,
lateout("$t5") _,
lateout("$t6") _,
lateout("$t7") _,
lateout("$t8") _,
options(nostack, preserves_flags)
);
ret
}

/// Issues a raw system call with 2 arguments.
///
/// # Safety
///
/// Running a system call is inherently unsafe. It is the caller's
/// responsibility to ensure safety.
#[inline]
pub unsafe fn syscall2(n: usize, arg1: usize, arg2: usize) -> usize {
let mut ret: usize;
asm!(
"syscall 0",
in("$a7") n,
inlateout("$a0") arg1 => ret,
in("$a1") arg2,
// All temporary registers are always clobbered
lateout("$t0") _,
lateout("$t1") _,
lateout("$t2") _,
lateout("$t3") _,
lateout("$t4") _,
lateout("$t5") _,
lateout("$t6") _,
lateout("$t7") _,
lateout("$t8") _,
options(nostack, preserves_flags)
);
ret
}

/// Issues a raw system call with 3 arguments.
///
/// # Safety
///
/// Running a system call is inherently unsafe. It is the caller's
/// responsibility to ensure safety.
#[inline]
pub unsafe fn syscall3(
n: usize,
arg1: usize,
arg2: usize,
arg3: usize,
) -> usize {
let mut ret: usize;
asm!(
"syscall 0",
in("$a7") n,
inlateout("$a0") arg1 => ret,
in("$a1") arg2,
in("$a2") arg3,
// All temporary registers are always clobbered
lateout("$t0") _,
lateout("$t1") _,
lateout("$t2") _,
lateout("$t3") _,
lateout("$t4") _,
lateout("$t5") _,
lateout("$t6") _,
lateout("$t7") _,
lateout("$t8") _,
options(nostack, preserves_flags)
);
ret
}

/// Issues a raw system call with 4 arguments.
///
/// # Safety
///
/// Running a system call is inherently unsafe. It is the caller's
/// responsibility to ensure safety.
#[inline]
pub unsafe fn syscall4(
n: usize,
arg1: usize,
arg2: usize,
arg3: usize,
arg4: usize,
) -> usize {
let mut ret: usize;
asm!(
"syscall 0",
in("$a7") n,
inlateout("$a0") arg1 => ret,
in("$a1") arg2,
in("$a2") arg3,
in("$a3") arg4,
// All temporary registers are always clobbered
lateout("$t0") _,
lateout("$t1") _,
lateout("$t2") _,
lateout("$t3") _,
lateout("$t4") _,
lateout("$t5") _,
lateout("$t6") _,
lateout("$t7") _,
lateout("$t8") _,
options(nostack, preserves_flags)
);
ret
}

/// Issues a raw system call with 5 arguments.
///
/// # Safety
///
/// Running a system call is inherently unsafe. It is the caller's
/// responsibility to ensure safety.
#[inline]
pub unsafe fn syscall5(
n: usize,
arg1: usize,
arg2: usize,
arg3: usize,
arg4: usize,
arg5: usize,
) -> usize {
let mut ret: usize;
asm!(
"syscall 0",
in("$a7") n,
inlateout("$a0") arg1 => ret,
in("$a1") arg2,
in("$a2") arg3,
in("$a3") arg4,
in("$a4") arg5,
// All temporary registers are always clobbered
lateout("$t0") _,
lateout("$t1") _,
lateout("$t2") _,
lateout("$t3") _,
lateout("$t4") _,
lateout("$t5") _,
lateout("$t6") _,
lateout("$t7") _,
lateout("$t8") _,
options(nostack, preserves_flags)
);
ret
}

/// Issues a raw system call with 6 arguments.
///
/// # Safety
///
/// Running a system call is inherently unsafe. It is the caller's
/// responsibility to ensure safety.
#[inline]
pub unsafe fn syscall6(
n: usize,
arg1: usize,
arg2: usize,
arg3: usize,
arg4: usize,
arg5: usize,
arg6: usize,
) -> usize {
let mut ret: usize;
asm!(
"syscall 0",
in("$a7") n,
inlateout("$a0") arg1 => ret,
in("$a1") arg2,
in("$a2") arg3,
in("$a3") arg4,
in("$a4") arg5,
in("$a5") arg6,
// All temporary registers are always clobbered
lateout("$t0") _,
lateout("$t1") _,
lateout("$t2") _,
lateout("$t3") _,
lateout("$t4") _,
lateout("$t5") _,
lateout("$t6") _,
lateout("$t7") _,
lateout("$t8") _,
options(nostack, preserves_flags)
);
ret
}
5 changes: 5 additions & 0 deletions src/syscall/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@ mod aarch64;
mod arm;
#[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))]
mod arm_thumb;
#[cfg(target_arch = "loongarch64")]
mod loongarch64;
#[cfg(target_arch = "mips")]
mod mips;
#[cfg(target_arch = "mips64")]
Expand Down Expand Up @@ -36,6 +38,9 @@ pub use arm::*;
#[cfg(all(target_arch = "arm", target_feature = "thumb-mode"))]
pub use arm_thumb::*;

#[cfg(target_arch = "loongarch64")]
pub use loongarch64::*;

#[cfg(target_arch = "mips")]
pub use mips::*;

Expand Down
9 changes: 9 additions & 0 deletions syscalls-gen/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,15 @@ lazy_static! {
],
blocklist: &["sync_file_range"],
}),
// For loongarch64, see aarch64's explanation.
Source::Header(Header {
arch: "loongarch64",
headers: &[
"include/uapi/asm-generic/unistd.h",
"arch/loongarch/include/uapi/asm/unistd.h",
],
blocklist: &["sync_file_range"],
}),
];
}

Expand Down
Loading