From f0e017f87e9a260f6bad007ad039a073477d02f3 Mon Sep 17 00:00:00 2001 From: arendelle Date: Sat, 18 Oct 2025 15:19:47 +0800 Subject: [PATCH 1/2] add inline_syscall to syscall with 2 param --- .../fast_io_hosted/platforms/linux/aarch64.h | 19 ++++++++++++++++ .../fast_io_hosted/platforms/linux/amd64.h | 21 ++++++++++++++++++ .../fast_io_hosted/platforms/linux/generic.h | 14 ++++++++++++ .../platforms/linux/loongarch64.h | 22 ++++++++++++++++++- .../fast_io_hosted/platforms/linux/riscv64.h | 19 ++++++++++++++++ 5 files changed, 94 insertions(+), 1 deletion(-) diff --git a/include/fast_io_hosted/platforms/linux/aarch64.h b/include/fast_io_hosted/platforms/linux/aarch64.h index f2458f5ca..621689181 100644 --- a/include/fast_io_hosted/platforms/linux/aarch64.h +++ b/include/fast_io_hosted/platforms/linux/aarch64.h @@ -1,5 +1,10 @@ #pragma once +#include +#include +#include +#include + namespace fast_io { @@ -24,6 +29,7 @@ inline return_value_type system_call(auto p1) noexcept } template <::std::uint_least64_t syscall_number> +[[noreturn]] inline void system_call_no_return(auto p1) noexcept { register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; @@ -43,6 +49,18 @@ inline return_value_type system_call(auto p1, auto p2) noexcept return static_cast(x0); } +template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> + requires(1 < sizeof(return_value_type)) +[[__gnu__::__always_inline__]] +inline return_value_type inline_syscall(auto p1, auto p2) noexcept +{ + register ::std::uint_least64_t x8 __asm__("x8") = syscall_number; + register ::std::uint_least64_t x0 __asm__("x0") = (::std::uint_least64_t)p1; + register ::std::uint_least64_t x1 __asm__("x1") = (::std::uint_least64_t)p2; + __asm__ __volatile__("svc 0" : "=r"(x0) : "r"(x8), "0"(x0), "r"(x1) : "memory", "cc"); + return static_cast(x0); +} + template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept @@ -101,6 +119,7 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5 } template <::std::integral I> +[[noreturn]] inline void fast_exit(I ret) noexcept { system_call_no_return<__NR_exit>(ret); diff --git a/include/fast_io_hosted/platforms/linux/amd64.h b/include/fast_io_hosted/platforms/linux/amd64.h index 5994ab9d0..2da7a907a 100644 --- a/include/fast_io_hosted/platforms/linux/amd64.h +++ b/include/fast_io_hosted/platforms/linux/amd64.h @@ -1,6 +1,11 @@ #pragma once // https://github.com/bminor/glibc/master/sysdeps/unix/sysv/linux/x86_64/sysdep.h +#include +#include +#include +#include + namespace fast_io { @@ -31,6 +36,7 @@ inline return_value_type system_call(auto p1) noexcept } template <::std::uint_least64_t syscall_number> +[[noreturn]] inline void system_call_no_return(auto p1) noexcept { ::std::uint_least64_t ret; @@ -55,6 +61,20 @@ inline return_value_type system_call(auto p1, auto p2) noexcept return ret; } +template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> + requires(1 < sizeof(return_value_type)) +[[__gnu__::__always_inline__]] +inline return_value_type inline_syscall(auto p1, auto p2) noexcept +{ + return_value_type ret; + __asm__ __volatile__("syscall" + : "=a"(ret) + // EDI RSI RDX + : "0"(syscall_number), "D"(p1), "S"(p2) + : "memory", "cc", "r11", "cx"); + return ret; +} + template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept @@ -114,6 +134,7 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5 } template <::std::integral I> +[[noreturn]] inline void fast_exit(I ret) noexcept { system_call_no_return<__NR_exit>(ret); diff --git a/include/fast_io_hosted/platforms/linux/generic.h b/include/fast_io_hosted/platforms/linux/generic.h index 5cc440f8a..794379e7d 100644 --- a/include/fast_io_hosted/platforms/linux/generic.h +++ b/include/fast_io_hosted/platforms/linux/generic.h @@ -1,4 +1,8 @@ #pragma once + +#include +#include +#include #include #include @@ -13,7 +17,16 @@ inline return_value_type system_call(Args... args) noexcept return static_cast(ret); } +template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> + requires(1 < sizeof(return_value_type)) +[[__gnu__::__always_inline__]] +inline return_value_type inline_syscall(auto p1, auto p2) noexcept +{ + static_assert(false, "force inline for generic syscall is not supported"); +} + template <::std::size_t syscall_number> +[[noreturn]] inline void system_call_no_return(auto p1) noexcept { ::syscall(syscall_number, p1); @@ -21,6 +34,7 @@ inline void system_call_no_return(auto p1) noexcept } template <::std::integral I> +[[noreturn]] inline void fast_exit(I ret) noexcept { system_call_no_return<__NR_exit>(ret); diff --git a/include/fast_io_hosted/platforms/linux/loongarch64.h b/include/fast_io_hosted/platforms/linux/loongarch64.h index d3dbe4868..07b10ba51 100644 --- a/include/fast_io_hosted/platforms/linux/loongarch64.h +++ b/include/fast_io_hosted/platforms/linux/loongarch64.h @@ -5,6 +5,11 @@ glibc loongarch loongarch syscall is very similar to riscv. but it is using syscall instruction like x86_64 */ +#include +#include +#include +#include + namespace fast_io { @@ -31,13 +36,14 @@ inline return_value_type system_call(auto p1) noexcept } template <::std::uint_least64_t syscall_number> +[[noreturn]] inline void system_call_no_return(auto p1) noexcept { register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; register ::std::uint_least64_t a0 __asm__("$a0") = (::std::uint_least64_t)p1; __asm__ __volatile__("syscall 0" : "+r"(a0) : "r"(a7) : "$t0", "$t1", "$t2", "$t3", "$t4", "$t5", "$t6", "$t7", "$t8", "memory"); - __builtin_unreachable(); + __builtin_unreachable(); } template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> @@ -52,6 +58,19 @@ inline return_value_type system_call(auto p1, auto p2) noexcept return static_cast(a0); } +template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> + requires(1 < sizeof(return_value_type)) +[[__gnu__::__always_inline__]] +inline return_value_type inline_syscall(auto p1, auto p2) noexcept +{ + register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number; + register ::std::uint_least64_t a0 __asm__("$a0") = (::std::uint_least64_t)p1; + register ::std::uint_least64_t a1 __asm__("$a1") = (::std::uint_least64_t)p2; + __asm__ __volatile__("syscall 0" : "+r"(a0) : "r"(a7), "r"(a1) : "$t0", "$t1", "$t2", "$t3", "$t4", + "$t5", "$t6", "$t7", "$t8", "memory"); + return static_cast(a0); +} + template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept @@ -111,6 +130,7 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5 } template <::std::integral I> +[[noreturn]] inline void fast_exit(I ret) noexcept { system_call_no_return<__NR_exit>(ret); diff --git a/include/fast_io_hosted/platforms/linux/riscv64.h b/include/fast_io_hosted/platforms/linux/riscv64.h index bdc1786d9..e9df0fffb 100644 --- a/include/fast_io_hosted/platforms/linux/riscv64.h +++ b/include/fast_io_hosted/platforms/linux/riscv64.h @@ -5,6 +5,11 @@ Do we need to deal with big endian with extra code??? */ +#include +#include +#include +#include + namespace fast_io { @@ -29,6 +34,7 @@ inline return_value_type system_call(auto p1) noexcept } template <::std::uint_least64_t syscall_number> +[[noreturn]] inline void system_call_no_return(auto p1) noexcept { register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; @@ -48,6 +54,18 @@ inline return_value_type system_call(auto p1, auto p2) noexcept return static_cast(a0); } +template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> + requires(1 < sizeof(return_value_type)) +[[__gnu__::__always_inline__]] +inline return_value_type inline_syscall(auto p1, auto p2) noexcept +{ + register ::std::uint_least64_t a7 __asm__("a7") = syscall_number; + register ::std::uint_least64_t a0 __asm__("a0") = (::std::uint_least64_t)p1; + register ::std::uint_least64_t a1 __asm__("a1") = (::std::uint_least64_t)p2; + __asm__ __volatile__("ecall" : "+r"(a0) : "r"(a7), "r"(a1) : "memory"); + return static_cast(a0); +} + template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type> requires(1 < sizeof(return_value_type)) inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept @@ -103,6 +121,7 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5 } template <::std::integral I> +[[noreturn]] inline void fast_exit(I ret) noexcept { system_call_no_return<__NR_exit>(ret); From 84c81f1387ff6c234a4f05729544ac3905221070 Mon Sep 17 00:00:00 2001 From: Arendelle Date: Mon, 20 Oct 2025 10:53:05 +0800 Subject: [PATCH 2/2] remove redundant sys/syscall.h --- include/fast_io_hosted/platforms/linux/aarch64.h | 1 - include/fast_io_hosted/platforms/linux/amd64.h | 1 - include/fast_io_hosted/platforms/linux/loongarch64.h | 1 - include/fast_io_hosted/platforms/linux/riscv64.h | 1 - 4 files changed, 4 deletions(-) diff --git a/include/fast_io_hosted/platforms/linux/aarch64.h b/include/fast_io_hosted/platforms/linux/aarch64.h index 621689181..44c3ddaa0 100644 --- a/include/fast_io_hosted/platforms/linux/aarch64.h +++ b/include/fast_io_hosted/platforms/linux/aarch64.h @@ -3,7 +3,6 @@ #include #include #include -#include namespace fast_io { diff --git a/include/fast_io_hosted/platforms/linux/amd64.h b/include/fast_io_hosted/platforms/linux/amd64.h index 2da7a907a..b6f097a55 100644 --- a/include/fast_io_hosted/platforms/linux/amd64.h +++ b/include/fast_io_hosted/platforms/linux/amd64.h @@ -4,7 +4,6 @@ #include #include #include -#include namespace fast_io { diff --git a/include/fast_io_hosted/platforms/linux/loongarch64.h b/include/fast_io_hosted/platforms/linux/loongarch64.h index 07b10ba51..5a4426b52 100644 --- a/include/fast_io_hosted/platforms/linux/loongarch64.h +++ b/include/fast_io_hosted/platforms/linux/loongarch64.h @@ -8,7 +8,6 @@ loongarch syscall is very similar to riscv. but it is using syscall instruction #include #include #include -#include namespace fast_io { diff --git a/include/fast_io_hosted/platforms/linux/riscv64.h b/include/fast_io_hosted/platforms/linux/riscv64.h index e9df0fffb..5d547e456 100644 --- a/include/fast_io_hosted/platforms/linux/riscv64.h +++ b/include/fast_io_hosted/platforms/linux/riscv64.h @@ -8,7 +8,6 @@ Do we need to deal with big endian with extra code??? #include #include #include -#include namespace fast_io {