summaryrefslogtreecommitdiff
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/build.ninja9
-rw-r--r--arch/x64/linux/syscall.S65
2 files changed, 74 insertions, 0 deletions
diff --git a/arch/build.ninja b/arch/build.ninja
new file mode 100644
index 0000000..42ee8f6
--- /dev/null
+++ b/arch/build.ninja
@@ -0,0 +1,9 @@
+rule gas
+ command = gcc -c $in -o $out
+
+rule archive
+ command = ar rcs $out $in
+
+build syscall.o: gas x64/linux/syscall.S
+
+build tanya.a: archive syscall.o
diff --git a/arch/x64/linux/syscall.S b/arch/x64/linux/syscall.S
new file mode 100644
index 0000000..9261d87
--- /dev/null
+++ b/arch/x64/linux/syscall.S
@@ -0,0 +1,65 @@
+/*
+The kernel uses the following registers:
+%rdi, %rsi, %rdx, %r8, %r9, %r10
+
+The number of the syscall is passed in %rax.
+
+A syscall clobbers:
+%rax, %rcx, %r11
+
+The returned value is placed in %rax.
+*/
+ .text
+
+ .globl syscall1
+ .type syscall1, @function
+
+syscall1:
+ movq %rsi, %rax // Syscall number.
+
+ syscall
+
+ ret
+
+
+ .globl syscall2
+ .type syscall2, @function
+
+syscall2:
+ // Store registers.
+ movq %rdi, %r8
+
+ movq %rdx, %rax // Syscall number.
+
+ // Syscall arguments.
+ movq %rsi, %rdi
+ movq %r8, %rsi
+
+ syscall
+
+ // Restore registers.
+ movq %rdi, %rsi
+ movq %r8, %rdi
+
+ ret
+
+
+ .globl syscall3
+ .type syscall3, @function
+
+syscall3:
+ // Store registers.
+ movq %rdi, %r8
+
+ movq %rcx, %rax // Syscall number.
+
+ // Syscall arguments.
+ movq %rdx, %rdi
+ movq %r8, %rdx
+
+ syscall
+
+ // Restore registers.
+ movq %r8, %rdi
+
+ ret