]> git.ipfire.org Git - thirdparty/glibc.git/blame - sysdeps/unix/sysv/linux/alpha/clone.S
update from main archive 970118
[thirdparty/glibc.git] / sysdeps / unix / sysv / linux / alpha / clone.S
CommitLineData
3b0174d0 1/* Copyright (C) 1996 Free Software Foundation, Inc.
3c7b2587
UD
2 This file is part of the GNU C Library.
3 Contributed by Richard Henderson <rth@tamu.edu>, 1996.
3b0174d0 4
3c7b2587
UD
5 The GNU C Library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public License as
7 published by the Free Software Foundation; either version 2 of the
8 License, or (at your option) any later version.
3b0174d0 9
3c7b2587
UD
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 Library General Public License for more details.
3b0174d0 14
3c7b2587
UD
15 You should have received a copy of the GNU Library General Public
16 License along with the GNU C Library; see the file COPYING.LIB. If not,
17 write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 Boston, MA 02111-1307, USA. */
3b0174d0
UD
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 <sysdep.h>
81e25b60 24#define _ERRNO_H 1
3b0174d0
UD
25#include <errnos.h>
26
27/* int clone(int (*fn)(), void *child_stack, int flags, int nargs, ...) */
28
29 .text
30ENTRY(__clone)
31 lda sp,-16(sp)
32 .frame sp,16,$26,0
33 /* Save rest of argument registers for varargs-type work. */
34 stq a4,0(sp)
35 stq a5,8(sp)
dd4b8913 36#ifdef PROF
3c7b2587 37 .set noat
dd4b8913
UD
38 lda AT, _mcount
39 jsr AT, (AT), _mcount
3c7b2587 40 .set at
dd4b8913 41#endif
3b0174d0
UD
42 .prologue 1
43
44 /* Sanity check arguments. */
45 sextl a3,a3
46 ldiq v0,EINVAL
47 beq a0,$error /* no NULL function pointers */
48 beq a1,$error /* no NULL stack pointers */
49 blt a3,$error /* no negative argument counts */
50
51 /* Allocate space on the new stack and copy args over */
52 mov a3,t0 /* save nargs for thread_start */
53 s8addq a3,sp,t1
541: ldq t2,-8(t1)
55 subq t1,8,t1
56 stq t2,-8(a1)
57 subq a3,1,a3
58 subq a1,8,a1
59 bne a3,1b
60
61 /* Do the system call */
62 mov a0,pv /* get fn ptr out of the way */
63 mov a2,a0
64 ldiq v0,__NR_clone
65 call_pal PAL_callsys
66
67 bne a3,$error
68 beq v0,thread_start
69
70 /* Successful return from the parent */
71 lda sp,16(sp)
72 ret
73
74 /* Something bad happened -- no child created */
75$error:
76 br gp,1f
771: ldgp gp,0(gp)
78 lda sp,16(sp)
79 jmp zero,__syscall_error
80
81 END(__clone)
82
83/* Load up the arguments to the function. Put this block of code in
84 its own function so that we can terminate the stack trace with our
85 debug info.
86
87 At this point we have $t0=nargs, $pv=fn, $sp=&arg[0]. */
88
89 .ent thread_start
90thread_start:
91 .frame fp,0,zero,0
92 mov zero,fp
93 .prologue 0
94
95 /* Calculate address of jump into argument loading code */
96 cmple t0,6,t2 /* no more than 6 args in registers */
97 cmoveq t2,6,t0
98 br v0,1f /* find address of arg0 */
991: lda v0,$arg0-1b(v0)
100 s4addq t0,zero,t1
101 subq v0,t1,v0
102 jmp (v0)
103
104 /* Load the integer register arguments */
105 ldq a5,40(sp)
106 ldq a4,32(sp)
107 ldq a3,24(sp)
108 ldq a2,16(sp)
109 ldq a1,8(sp)
110 ldq a0,0(sp)
111$arg0:
112
113 /* Adjust stack to remove the arguments we just loaded */
114 s8addq t0,sp,sp
115
116 /* Call the user's function */
117 jsr ra,(pv)
118 ldgp gp,0(ra)
119
120 /* Call _exit rather than doing it inline for breakpoint purposes */
121 mov v0,a0
122 jsr ra,_exit
123
124 .end thread_start
125
126weak_alias(__clone, clone)