Skip to content
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
18 changes: 18 additions & 0 deletions include/fast_io_hosted/platforms/linux/aarch64.h
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
#pragma once

#include <cstddef>
#include <cstdint>
#include <concepts>

namespace fast_io
{

Expand All @@ -24,6 +28,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;
Expand All @@ -43,6 +48,18 @@ inline return_value_type system_call(auto p1, auto p2) noexcept
return static_cast<return_value_type>(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<return_value_type>(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
Expand Down Expand Up @@ -101,6 +118,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);
Expand Down
20 changes: 20 additions & 0 deletions include/fast_io_hosted/platforms/linux/amd64.h
Original file line number Diff line number Diff line change
@@ -1,6 +1,10 @@
#pragma once
// https://github.com/bminor/glibc/master/sysdeps/unix/sysv/linux/x86_64/sysdep.h

#include <cstddef>
#include <cstdint>
#include <concepts>

namespace fast_io
{

Expand Down Expand Up @@ -31,6 +35,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;
Expand All @@ -55,6 +60,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
Expand Down Expand Up @@ -114,6 +133,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);
Expand Down
14 changes: 14 additions & 0 deletions include/fast_io_hosted/platforms/linux/generic.h
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
#pragma once

#include <cstddef>
#include <cstdint>
#include <concepts>
#include <unistd.h>
#include <sys/syscall.h>

Expand All @@ -13,14 +17,24 @@ inline return_value_type system_call(Args... args) noexcept
return static_cast<return_value_type>(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);
__builtin_unreachable();
}

template <::std::integral I>
[[noreturn]]
inline void fast_exit(I ret) noexcept
{
system_call_no_return<__NR_exit>(ret);
Expand Down
21 changes: 20 additions & 1 deletion include/fast_io_hosted/platforms/linux/loongarch64.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@ glibc loongarch
loongarch syscall is very similar to riscv. but it is using syscall instruction like x86_64
*/

#include <cstddef>
#include <cstdint>
#include <concepts>

namespace fast_io
{

Expand All @@ -31,13 +35,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>
Expand All @@ -52,6 +57,19 @@ inline return_value_type system_call(auto p1, auto p2) noexcept
return static_cast<return_value_type>(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<return_value_type>(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
Expand Down Expand Up @@ -111,6 +129,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);
Expand Down
18 changes: 18 additions & 0 deletions include/fast_io_hosted/platforms/linux/riscv64.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,10 @@
Do we need to deal with big endian with extra code???
*/

#include <cstddef>
#include <cstdint>
#include <concepts>

namespace fast_io
{

Expand All @@ -29,6 +33,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;
Expand All @@ -48,6 +53,18 @@ inline return_value_type system_call(auto p1, auto p2) noexcept
return static_cast<return_value_type>(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<return_value_type>(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
Expand Down Expand Up @@ -103,6 +120,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);
Expand Down