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.

80 lines
1.9 KiB

  1. #pragma once
  2. #include <cstdint>
  3. #include <cstddef>
  4. #include <gp/containers/buffer.hpp>
  5. template<int64_t syscall_id, int arg_count>
  6. struct syscall;
  7. template<int64_t syscall_id>
  8. struct syscall<syscall_id, 1> {
  9. int64_t operator()(int64_t p1) const {
  10. int64_t ret;
  11. asm volatile
  12. (
  13. "syscall"
  14. : "=a" (ret)
  15. : "0"(syscall_id), "D"(p1)
  16. : "rcx", "r11", "memory"
  17. );
  18. return ret;
  19. }
  20. };
  21. template<int64_t syscall_id>
  22. struct syscall<syscall_id, 2> {
  23. int64_t operator()(int64_t p1,int64_t p2) const {
  24. int64_t ret;
  25. asm volatile
  26. (
  27. "syscall"
  28. : "=a" (ret)
  29. : "0"(syscall_id), "D"(p1), "S"(p2)
  30. : "rcx", "r11", "memory"
  31. );
  32. return ret;
  33. }
  34. };
  35. template<int64_t syscall_id>
  36. struct syscall<syscall_id, 3> {
  37. int64_t operator()(int64_t p1,int64_t p2,int64_t p3) const {
  38. int64_t ret;
  39. asm volatile
  40. (
  41. "syscall"
  42. : "=a" (ret)
  43. : "0"(syscall_id), "D"(p1), "S"(p2), "d"(p3)
  44. : "rcx", "r11", "memory"
  45. );
  46. return ret;
  47. }
  48. };
  49. constexpr auto _read = syscall<0, 3>{};
  50. constexpr auto _write = syscall<1, 3>{};
  51. constexpr auto _exit = syscall<60, 1>{};
  52. inline int read(int fd, char* buffer, size_t sz) {
  53. return _read((int64_t)fd, (int64_t)buffer, (int64_t)sz);
  54. }
  55. inline int write(int fd, char* buffer, size_t sz) {
  56. return _write((int64_t)fd, (int64_t)buffer, (int64_t)sz);
  57. }
  58. inline int read(int fd, gp::buffer<char> buffer) {
  59. return _read((int64_t)fd, (int64_t)buffer.begin().data, (int64_t)buffer.size());
  60. }
  61. inline int write(int fd, gp::buffer<char> buffer) {
  62. return _write((int64_t)fd, (int64_t)buffer.begin().data, (int64_t)buffer.size());
  63. }
  64. extern "C" {
  65. inline __attribute__ ((__noreturn__)) void exit(int status) {
  66. _exit((int64_t)status);
  67. while(true);
  68. }
  69. }