]> rtime.felk.cvut.cz Git - l4.git/blob - l4/pkg/uclibc/lib/contrib/uclibc/libc/sysdeps/linux/alpha/clone.S
Inital import
[l4.git] / l4 / pkg / uclibc / lib / contrib / uclibc / libc / sysdeps / linux / alpha / clone.S
1 /* Copyright (C) 1996, 1997 Free Software Foundation, Inc.
2    This file is part of the GNU C Library.
3    Contributed by Richard Henderson <rth@tamu.edu>, 1996.
4
5    The GNU C Library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2.1 of the License, or (at your option) any later version.
9
10    The GNU C Library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with the GNU C Library; if not, write to the Free
17    Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
18    02111-1307 USA.  */
19
20 /* clone() is even more special than fork() as it mucks with stacks
21    and invokes a function in the right context after its all over.  */
22
23 #include <features.h>
24 #define _ERRNO_H        1
25 #include <bits/errno.h>
26 #include <sys/syscall.h>
27 #include <sys/regdef.h>
28
29 /* int clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg) */
30
31 .text
32 .globl  clone;
33 .align 3;
34 .ent  clone , 0;
35
36 clone:
37         .frame $30 , 0, $26
38         .prologue 0
39
40         /* Sanity check arguments.  */
41         ldiq    v0,EINVAL
42         beq     a0,$error               /* no NULL function pointers */
43         beq     a1,$error               /* no NULL stack pointers */
44
45         /* Save the fn ptr and arg on the new stack.  */
46         subq    a1,16,a1
47         stq     a0,0(a1)
48         stq     a3,8(a1)
49
50         /* Do the system call */
51         mov     a2,a0
52         ldiq    v0,__NR_clone
53         call_pal 131
54
55         bne     a3,$error
56         beq     v0,thread_start
57
58         /* Successful return from the parent */
59         ret
60
61         /* Something bad happened -- no child created */
62 $error:
63         br      gp,1f
64 1:      ldgp    gp,0(gp)
65         jmp     zero,__syscall_error
66
67 .end clone
68
69 /* Load up the arguments to the function.  Put this block of code in
70    its own function so that we can terminate the stack trace with our
71    debug info.  */
72
73         .ent thread_start
74 thread_start:
75         .frame fp,0,zero,0
76         mov     zero,fp
77         .prologue 0
78
79         /* Load up the arguments.  */
80         ldq     pv,0($30)
81         ldq     a0,8($30)
82         addq    $30,16,$30
83
84         /* Call the user's function */
85         jsr     ra,(pv)
86         ldgp    gp,0(ra)
87
88         /* Call _exit rather than doing it inline for breakpoint purposes */
89         mov     v0,a0
90         jsr     ra,HIDDEN_JUMPTARGET(_exit)
91
92         /* Die horribly.  */
93         halt
94
95         .end thread_start