aboutsummaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorAlex Rønne Petersen <alex@alexrp.com>2024-06-22 14:52:31 +0200
committerAlex Rønne Petersen <alex@alexrp.com>2024-07-29 09:50:09 +0200
commitb958225e687c3b044d52a5adcb58dfb413ee141a (patch)
treeb1b827e234af368b4e9b584f16579e2f1d4b0642 /lib
parent8b176ab303724054f0fcef21c3d849c377b54421 (diff)
downloadzig-b958225e687c3b044d52a5adcb58dfb413ee141a.tar.gz
zig-b958225e687c3b044d52a5adcb58dfb413ee141a.zip
c: Implement clone() for riscv32-linux.
Diffstat (limited to 'lib')
-rw-r--r--lib/c.zig34
1 files changed, 34 insertions, 0 deletions
diff --git a/lib/c.zig b/lib/c.zig
index 0534013d3b..50f1d74e7d 100644
--- a/lib/c.zig
+++ b/lib/c.zig
@@ -319,6 +319,40 @@ fn clone() callconv(.Naked) void {
\\3: bx r5
);
},
+ .riscv32 => {
+ // __clone(func, stack, flags, arg, ptid, tls, ctid)
+ // a0, a1, a2, a3, a4, a5, a6
+
+ // syscall(SYS_clone, flags, stack, ptid, tls, ctid)
+ // a7 a0, a1, a2, a3, a4
+ asm volatile (
+ \\ # Save func and arg to stack
+ \\ addi a1, a1, -8
+ \\ sw a0, 0(a1)
+ \\ sw a3, 4(a1)
+ \\
+ \\ # Call SYS_clone
+ \\ mv a0, a2
+ \\ mv a2, a4
+ \\ mv a3, a5
+ \\ mv a4, a6
+ \\ li a7, 220 # SYS_clone
+ \\ ecall
+ \\
+ \\ beqz a0, 1f
+ \\ # Parent
+ \\ ret
+ \\
+ \\ # Child
+ \\1: lw a1, 0(sp)
+ \\ lw a0, 4(sp)
+ \\ jalr a1
+ \\
+ \\ # Exit
+ \\ li a7, 93 # SYS_exit
+ \\ ecall
+ );
+ },
.riscv64 => {
// __clone(func, stack, flags, arg, ptid, tls, ctid)
// a0, a1, a2, a3, a4, a5, a6