General Purpose library for Freestanding C++ and POSIX systems
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

81 lines
1.9 KiB

#pragma once
#include <cstdint>
#include <cstddef>
#include <gp/containers/buffer.hpp>
template<int64_t syscall_id, int arg_count>
struct syscall;
template<int64_t syscall_id>
struct syscall<syscall_id, 1> {
int64_t operator()(int64_t p1) const {
int64_t ret;
asm volatile
(
"syscall"
: "=a" (ret)
: "0"(syscall_id), "D"(p1)
: "rcx", "r11", "memory"
);
return ret;
}
};
template<int64_t syscall_id>
struct syscall<syscall_id, 2> {
int64_t operator()(int64_t p1,int64_t p2) const {
int64_t ret;
asm volatile
(
"syscall"
: "=a" (ret)
: "0"(syscall_id), "D"(p1), "S"(p2)
: "rcx", "r11", "memory"
);
return ret;
}
};
template<int64_t syscall_id>
struct syscall<syscall_id, 3> {
int64_t operator()(int64_t p1,int64_t p2,int64_t p3) const {
int64_t ret;
asm volatile
(
"syscall"
: "=a" (ret)
: "0"(syscall_id), "D"(p1), "S"(p2), "d"(p3)
: "rcx", "r11", "memory"
);
return ret;
}
};
constexpr auto _read = syscall<0, 3>{};
constexpr auto _write = syscall<1, 3>{};
constexpr auto _exit = syscall<60, 1>{};
inline int read(int fd, char* buffer, size_t sz) {
return _read((int64_t)fd, (int64_t)buffer, (int64_t)sz);
}
inline int write(int fd, char* buffer, size_t sz) {
return _write((int64_t)fd, (int64_t)buffer, (int64_t)sz);
}
inline int read(int fd, gp::buffer<char> buffer) {
return _read((int64_t)fd, (int64_t)buffer.begin().data, (int64_t)buffer.size());
}
inline int write(int fd, gp::buffer<char> buffer) {
return _write((int64_t)fd, (int64_t)buffer.begin().data, (int64_t)buffer.size());
}
extern "C" {
inline __attribute__ ((__noreturn__)) void exit(int status) {
_exit((int64_t)status);
while(true);
}
}