1/*
2  Copyright 2015 Yoshinori Sato <ysato@users.sourceforge.jp>
3*/
4
5/* clone is even more special than fork as it mucks with stacks
6   and invokes a function in the right context after its all over.  */
7
8#define _ERRNO_H
9#include <bits/errno.h>
10#include <sys/syscall.h>
11
12/* int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg
13		void *parent_tidptr, void *tls, void *child_tidptr)  */
14
15#ifdef __H8300H__
16	.h8300h
17#endif
18#ifdef __H8300S__
19	.h8300s
20#endif
21
22.text
23.globl	clone
24clone:
25	/* Sanity check arguments.  */
26	mov.l	#-EINVAL,er3
27	mov.l	er0,er0			/* no NULL function pointers */
28	beq	__syscall_error
29	mov.l	er1,er1			/* no NULL stack pointers */
30	beq	__syscall_error
31
32	/* Allocate space and copy the argument onto the new stack.  */
33	mov.l	@(4:16,sp),er3
34	mov.l	er3,@-er1
35
36	/* setup argument */
37	mov.l	er0,er3			/* er3 = child entry */
38	sub.l	#20,sp
39	mov.l	er2,@sp			/* flags */
40	mov.l	er1,@(4,sp)		/* new sp */
41	mov.l	sp,er1
42	mov.l	@(20+8,sp),er0
43	mov.l	er0,@er1		/* parent tid */
44	adds	#4,er1
45	mov.l	@(20+16,sp),er0
46	mov.l	er0,@er1		/* child tid */
47	adds	#4,er1
48	mov.l	@(20+12,sp),er0
49	mov.l	er0,@er1		/* tls */
50	/* do the system call */
51	mov.l	sp,er1
52	mov.l	#__NR_clone,er0
53	trapa	#0
54	add.l	#20,sp
55	mov.l	er0,er0
56	bmi	__syscall_error
57	beq	thread_start
58
59	rts
60
61__syscall_error:
62	neg.l	er0
63	mov.l	er0,@-sp
64#if !defined(__PIC__)
65	jsr	@__errno_location
66#else
67	mov.l	@(__errno_location@GOTOFF,er5),er1
68	jsr	@er1
69#endif
70	mov.l	@sp,er1
71	mov.l	er1,@er0
72	sub.l	er0,er0
73	dec.l	#1,er0
74
75	rts
76
77thread_start:
78	mov.l	@sp+,er0		/* restore args */
79	jsr	@er3
80	mov.l	er0,er1
81	mov.l	#__NR_exit,er0
82	trapa	#0
83
84	.end
85