Skip to content

Commit 31070d2

Browse files
add inline_syscall to syscall with 2 param (#1202)
* add inline_syscall to syscall with 2 param * remove redundant sys/syscall.h
1 parent d2796f2 commit 31070d2

File tree

5 files changed

+90
-1
lines changed

5 files changed

+90
-1
lines changed

include/fast_io_hosted/platforms/linux/aarch64.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
#pragma once
22

3+
#include <cstddef>
4+
#include <cstdint>
5+
#include <concepts>
6+
37
namespace fast_io
48
{
59

@@ -24,6 +28,7 @@ inline return_value_type system_call(auto p1) noexcept
2428
}
2529

2630
template <::std::uint_least64_t syscall_number>
31+
[[noreturn]]
2732
inline void system_call_no_return(auto p1) noexcept
2833
{
2934
register ::std::uint_least64_t x8 __asm__("x8") = syscall_number;
@@ -43,6 +48,18 @@ inline return_value_type system_call(auto p1, auto p2) noexcept
4348
return static_cast<return_value_type>(x0);
4449
}
4550

51+
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
52+
requires(1 < sizeof(return_value_type))
53+
[[__gnu__::__always_inline__]]
54+
inline return_value_type inline_syscall(auto p1, auto p2) noexcept
55+
{
56+
register ::std::uint_least64_t x8 __asm__("x8") = syscall_number;
57+
register ::std::uint_least64_t x0 __asm__("x0") = (::std::uint_least64_t)p1;
58+
register ::std::uint_least64_t x1 __asm__("x1") = (::std::uint_least64_t)p2;
59+
__asm__ __volatile__("svc 0" : "=r"(x0) : "r"(x8), "0"(x0), "r"(x1) : "memory", "cc");
60+
return static_cast<return_value_type>(x0);
61+
}
62+
4663
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
4764
requires(1 < sizeof(return_value_type))
4865
inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept
@@ -101,6 +118,7 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5
101118
}
102119

103120
template <::std::integral I>
121+
[[noreturn]]
104122
inline void fast_exit(I ret) noexcept
105123
{
106124
system_call_no_return<__NR_exit>(ret);

include/fast_io_hosted/platforms/linux/amd64.h

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,10 @@
11
#pragma once
22
// https://github.com/bminor/glibc/master/sysdeps/unix/sysv/linux/x86_64/sysdep.h
33

4+
#include <cstddef>
5+
#include <cstdint>
6+
#include <concepts>
7+
48
namespace fast_io
59
{
610

@@ -31,6 +35,7 @@ inline return_value_type system_call(auto p1) noexcept
3135
}
3236

3337
template <::std::uint_least64_t syscall_number>
38+
[[noreturn]]
3439
inline void system_call_no_return(auto p1) noexcept
3540
{
3641
::std::uint_least64_t ret;
@@ -55,6 +60,20 @@ inline return_value_type system_call(auto p1, auto p2) noexcept
5560
return ret;
5661
}
5762

63+
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
64+
requires(1 < sizeof(return_value_type))
65+
[[__gnu__::__always_inline__]]
66+
inline return_value_type inline_syscall(auto p1, auto p2) noexcept
67+
{
68+
return_value_type ret;
69+
__asm__ __volatile__("syscall"
70+
: "=a"(ret)
71+
// EDI RSI RDX
72+
: "0"(syscall_number), "D"(p1), "S"(p2)
73+
: "memory", "cc", "r11", "cx");
74+
return ret;
75+
}
76+
5877
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
5978
requires(1 < sizeof(return_value_type))
6079
inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept
@@ -114,6 +133,7 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5
114133
}
115134

116135
template <::std::integral I>
136+
[[noreturn]]
117137
inline void fast_exit(I ret) noexcept
118138
{
119139
system_call_no_return<__NR_exit>(ret);

include/fast_io_hosted/platforms/linux/generic.h

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,8 @@
11
#pragma once
2+
3+
#include <cstddef>
4+
#include <cstdint>
5+
#include <concepts>
26
#include <unistd.h>
37
#include <sys/syscall.h>
48

@@ -13,14 +17,24 @@ inline return_value_type system_call(Args... args) noexcept
1317
return static_cast<return_value_type>(ret);
1418
}
1519

20+
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
21+
requires(1 < sizeof(return_value_type))
22+
[[__gnu__::__always_inline__]]
23+
inline return_value_type inline_syscall(auto p1, auto p2) noexcept
24+
{
25+
static_assert(false, "force inline for generic syscall is not supported");
26+
}
27+
1628
template <::std::size_t syscall_number>
29+
[[noreturn]]
1730
inline void system_call_no_return(auto p1) noexcept
1831
{
1932
::syscall(syscall_number, p1);
2033
__builtin_unreachable();
2134
}
2235

2336
template <::std::integral I>
37+
[[noreturn]]
2438
inline void fast_exit(I ret) noexcept
2539
{
2640
system_call_no_return<__NR_exit>(ret);

include/fast_io_hosted/platforms/linux/loongarch64.h

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@ glibc loongarch
55
loongarch syscall is very similar to riscv. but it is using syscall instruction like x86_64
66
*/
77

8+
#include <cstddef>
9+
#include <cstdint>
10+
#include <concepts>
11+
812
namespace fast_io
913
{
1014

@@ -31,13 +35,14 @@ inline return_value_type system_call(auto p1) noexcept
3135
}
3236

3337
template <::std::uint_least64_t syscall_number>
38+
[[noreturn]]
3439
inline void system_call_no_return(auto p1) noexcept
3540
{
3641
register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number;
3742
register ::std::uint_least64_t a0 __asm__("$a0") = (::std::uint_least64_t)p1;
3843
__asm__ __volatile__("syscall 0" : "+r"(a0) : "r"(a7) : "$t0", "$t1", "$t2", "$t3", "$t4",
3944
"$t5", "$t6", "$t7", "$t8", "memory");
40-
__builtin_unreachable();
45+
__builtin_unreachable();
4146
}
4247

4348
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
@@ -52,6 +57,19 @@ inline return_value_type system_call(auto p1, auto p2) noexcept
5257
return static_cast<return_value_type>(a0);
5358
}
5459

60+
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
61+
requires(1 < sizeof(return_value_type))
62+
[[__gnu__::__always_inline__]]
63+
inline return_value_type inline_syscall(auto p1, auto p2) noexcept
64+
{
65+
register ::std::uint_least64_t a7 __asm__("$a7") = syscall_number;
66+
register ::std::uint_least64_t a0 __asm__("$a0") = (::std::uint_least64_t)p1;
67+
register ::std::uint_least64_t a1 __asm__("$a1") = (::std::uint_least64_t)p2;
68+
__asm__ __volatile__("syscall 0" : "+r"(a0) : "r"(a7), "r"(a1) : "$t0", "$t1", "$t2", "$t3", "$t4",
69+
"$t5", "$t6", "$t7", "$t8", "memory");
70+
return static_cast<return_value_type>(a0);
71+
}
72+
5573
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
5674
requires(1 < sizeof(return_value_type))
5775
inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept
@@ -111,6 +129,7 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5
111129
}
112130

113131
template <::std::integral I>
132+
[[noreturn]]
114133
inline void fast_exit(I ret) noexcept
115134
{
116135
system_call_no_return<__NR_exit>(ret);

include/fast_io_hosted/platforms/linux/riscv64.h

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,10 @@
55
Do we need to deal with big endian with extra code???
66
*/
77

8+
#include <cstddef>
9+
#include <cstdint>
10+
#include <concepts>
11+
812
namespace fast_io
913
{
1014

@@ -29,6 +33,7 @@ inline return_value_type system_call(auto p1) noexcept
2933
}
3034

3135
template <::std::uint_least64_t syscall_number>
36+
[[noreturn]]
3237
inline void system_call_no_return(auto p1) noexcept
3338
{
3439
register ::std::uint_least64_t a7 __asm__("a7") = syscall_number;
@@ -48,6 +53,18 @@ inline return_value_type system_call(auto p1, auto p2) noexcept
4853
return static_cast<return_value_type>(a0);
4954
}
5055

56+
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
57+
requires(1 < sizeof(return_value_type))
58+
[[__gnu__::__always_inline__]]
59+
inline return_value_type inline_syscall(auto p1, auto p2) noexcept
60+
{
61+
register ::std::uint_least64_t a7 __asm__("a7") = syscall_number;
62+
register ::std::uint_least64_t a0 __asm__("a0") = (::std::uint_least64_t)p1;
63+
register ::std::uint_least64_t a1 __asm__("a1") = (::std::uint_least64_t)p2;
64+
__asm__ __volatile__("ecall" : "+r"(a0) : "r"(a7), "r"(a1) : "memory");
65+
return static_cast<return_value_type>(a0);
66+
}
67+
5168
template <::std::uint_least64_t syscall_number, ::std::signed_integral return_value_type>
5269
requires(1 < sizeof(return_value_type))
5370
inline return_value_type system_call(auto p1, auto p2, auto p3) noexcept
@@ -103,6 +120,7 @@ inline return_value_type system_call(auto p1, auto p2, auto p3, auto p4, auto p5
103120
}
104121

105122
template <::std::integral I>
123+
[[noreturn]]
106124
inline void fast_exit(I ret) noexcept
107125
{
108126
system_call_no_return<__NR_exit>(ret);

0 commit comments

Comments
 (0)