summaryrefslogtreecommitdiffstats
path: root/libc-top-half/musl/src/thread/powerpc
diff options
context:
space:
mode:
Diffstat (limited to 'libc-top-half/musl/src/thread/powerpc')
-rw-r--r--libc-top-half/musl/src/thread/powerpc/__set_thread_area.s12
-rw-r--r--libc-top-half/musl/src/thread/powerpc/__unmapself.s9
-rw-r--r--libc-top-half/musl/src/thread/powerpc/clone.s73
-rw-r--r--libc-top-half/musl/src/thread/powerpc/syscall_cp.s59
4 files changed, 153 insertions, 0 deletions
diff --git a/libc-top-half/musl/src/thread/powerpc/__set_thread_area.s b/libc-top-half/musl/src/thread/powerpc/__set_thread_area.s
new file mode 100644
index 0000000..86c498f
--- /dev/null
+++ b/libc-top-half/musl/src/thread/powerpc/__set_thread_area.s
@@ -0,0 +1,12 @@
+.text
+.global __set_thread_area
+.hidden __set_thread_area
+.type __set_thread_area, %function
+__set_thread_area:
+ # mov pointer in reg3 into r2
+ mr 2, 3
+ # put 0 into return reg
+ li 3, 0
+ # return
+ blr
+
diff --git a/libc-top-half/musl/src/thread/powerpc/__unmapself.s b/libc-top-half/musl/src/thread/powerpc/__unmapself.s
new file mode 100644
index 0000000..c9360b4
--- /dev/null
+++ b/libc-top-half/musl/src/thread/powerpc/__unmapself.s
@@ -0,0 +1,9 @@
+ .text
+ .global __unmapself
+ .type __unmapself,%function
+__unmapself:
+ li 0, 91 # __NR_munmap
+ sc
+ li 0, 1 #__NR_exit
+ sc
+ blr
diff --git a/libc-top-half/musl/src/thread/powerpc/clone.s b/libc-top-half/musl/src/thread/powerpc/clone.s
new file mode 100644
index 0000000..da13f44
--- /dev/null
+++ b/libc-top-half/musl/src/thread/powerpc/clone.s
@@ -0,0 +1,73 @@
+.text
+.global __clone
+.hidden __clone
+.type __clone, %function
+__clone:
+# int clone(fn, stack, flags, arg, ptid, tls, ctid)
+# a b c d e f g
+# 3 4 5 6 7 8 9
+# pseudo C code:
+# tid = syscall(SYS_clone,c,b,e,f,g);
+# if (!tid) syscall(SYS_exit, a(d));
+# return tid;
+
+# SYS_clone = 120
+# SYS_exit = 1
+
+# store non-volatile regs r30, r31 on stack in order to put our
+# start func and its arg there
+stwu 30, -16(1)
+stw 31, 4(1)
+
+# save r3 (func) into r30, and r6(arg) into r31
+mr 30, 3
+mr 31, 6
+
+# create initial stack frame for new thread
+clrrwi 4, 4, 4
+li 0, 0
+stwu 0, -16(4)
+
+#move c into first arg
+mr 3, 5
+#mr 4, 4
+mr 5, 7
+mr 6, 8
+mr 7, 9
+
+# move syscall number into r0
+li 0, 120
+
+sc
+
+# check for syscall error
+bns+ 1f # jump to label 1 if no summary overflow.
+#else
+neg 3, 3 #negate the result (errno)
+1:
+# compare sc result with 0
+cmpwi cr7, 3, 0
+
+# if not 0, jump to end
+bne cr7, 2f
+
+#else: we're the child
+#call funcptr: move arg (d) into r3
+mr 3, 31
+#move r30 (funcptr) into CTR reg
+mtctr 30
+# call CTR reg
+bctrl
+# mov SYS_exit into r0 (the exit param is already in r3)
+li 0, 1
+sc
+
+2:
+
+# restore stack
+lwz 30, 0(1)
+lwz 31, 4(1)
+addi 1, 1, 16
+
+blr
+
diff --git a/libc-top-half/musl/src/thread/powerpc/syscall_cp.s b/libc-top-half/musl/src/thread/powerpc/syscall_cp.s
new file mode 100644
index 0000000..77f8938
--- /dev/null
+++ b/libc-top-half/musl/src/thread/powerpc/syscall_cp.s
@@ -0,0 +1,59 @@
+.global __cp_begin
+.hidden __cp_begin
+.global __cp_end
+.hidden __cp_end
+.global __cp_cancel
+.hidden __cp_cancel
+.hidden __cancel
+.global __syscall_cp_asm
+.hidden __syscall_cp_asm
+
+#r0: volatile. may be modified during linkage.
+#r1: stack frame: 16 byte alignment.
+#r2: tls/thread pointer on pp32
+#r3,r4: return values, first args
+#r5-r10: args
+#r11-r12: volatile. may be modified during linkage
+#r13: "small data area" pointer
+#r14 - r30: local vars
+#r31: local or environment pointer
+
+#r1, r14-31: belong to the caller, must be saved and restored
+#r0, r3-r12, ctr, xer: volatile, not preserved
+#r0,r11,r12: may be altered by cross-module call,
+#"a func cannot depend on that these regs have the values placed by the caller"
+
+#the fields CR2,CR2,CR4 of the cond reg must be preserved
+#LR (link reg) shall contain the funcs return address
+ .text
+ .type __syscall_cp_asm,%function
+__syscall_cp_asm:
+ # at enter: r3 = pointer to self->cancel, r4: syscall no, r5: first arg, r6: 2nd, r7: 3rd, r8: 4th, r9: 5th, r10: 6th
+__cp_begin:
+ # r3 holds first argument, its a pointer to self->cancel.
+ # we must compare the dereferenced value with 0 and jump to __cancel if its not
+
+ lwz 0, 0(3) #deref pointer into r0
+
+ cmpwi cr7, 0, 0 #compare r0 with 0, store result in cr7.
+ beq+ cr7, 1f #jump to label 1 if r0 was 0
+
+ b __cp_cancel #else call cancel
+1:
+ #ok, the cancel flag was not set
+ # syscall: number goes to r0, the rest 3-8
+ mr 0, 4 # put the system call number into r0
+ mr 3, 5 # Shift the arguments: arg1
+ mr 4, 6 # arg2
+ mr 5, 7 # arg3
+ mr 6, 8 # arg4
+ mr 7, 9 # arg5
+ mr 8, 10 # arg6
+ sc
+__cp_end:
+ bnslr+ # return if no summary overflow.
+ #else negate result.
+ neg 3, 3
+ blr
+__cp_cancel:
+ b __cancel