07280031a553b358c8e387a0a0707df4e091ebbc
[kopensolaris-gnu/glibc.git] / sysdeps / unix / sysv / linux / m68k / clone.S
1 /* Copyright (C) 1996 Free Software Foundation, Inc.
2    Contributed by Andreas Schwab (schwab@issan.informatik.uni-dortmund.de)
3
4 The GNU C Library is free software; you can redistribute it and/or
5 modify it under the terms of the GNU Library General Public License as
6 published by the Free Software Foundation; either version 2 of the
7 License, or (at your option) any later version.
8
9 The GNU C Library is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12 Library General Public License for more details.
13
14 You should have received a copy of the GNU Library General Public
15 License along with the GNU C Library; see the file COPYING.LIB.  If
16 not, write to the Free Software Foundation, Inc., 675 Mass Ave,
17 Cambridge, MA 02139, USA.  */
18
19 /* clone is even more special than fork as it mucks with stacks
20    and invokes a function in the right context after its all over.  */
21
22 #include <sysdep.h>
23 #define _ERRNO_H        1
24 #include <errnos.h>
25
26 /* int clone (int (*fn) (), void *child_stack, int flags, int nargs, ...) */
27
28         .text
29 ENTRY (__clone)
30         /* Sanity check arguments.  */
31         movel   #-EINVAL, %d0
32         movel   4(%sp), %a0             /* no NULL function pointers */
33         tstl    %a0
34         jeq     syscall_error
35         movel   8(%sp), %a1             /* no NULL stack pointers */
36         tstl    %a1
37         jeq     syscall_error
38         movel   16(%sp), %d1            /* no negative argument counts */
39         jmi     syscall_error
40
41         /* Allocate space on the new stack and copy args over */
42         movel   %d1, %d0
43         negl    %d0
44         lea     (%a1,%d0.l*4), %a1
45         jeq     2f
46 1:      movel   16(%sp,%d1.l*4), -4(%a1,%d1.l*4)
47         subql   #1, %d1
48         jne     1b
49 2:
50
51         /* Do the system call */
52         exg     %d2, %a1                /* save %d2 and get stack pointer */
53         movel   12(%sp), %d1            /* get flags */
54         movel   #SYS_ify (clone), %d0
55         trap    #0
56         exg     %d2, %a1                /* restore %d2 */
57
58         tstl    %d0
59         jmi     syscall_error
60         jeq     thread_start
61
62         rts
63
64         SYSCALL_ERROR_HANDLER
65
66 thread_start:
67         subl    %fp, %fp        /* terminate the stack frame */
68         jsr     (%a0)
69         movel   %d0, -(%sp)
70 #ifdef PIC
71         bsrl    _exit@PLTPC
72 #else
73         jbsr    _exit
74 #endif
75
76 weak_alias (__clone, clone)