/* Adapted from glibc */ /* Copyright (C) 1996, 1997 Free Software Foundation, Inc. */ /* clone is even more special than fork as it mucks with stacks and invokes a function in the right context after its all over. */ #define _ERRNO_H #include #include /* int _clone(int (*fn)(void *arg), void *child_stack, int flags, void *arg); */ #ifdef __H8300H__ .h8300h #endif #ifdef __H8300S__ .h8300s #endif .text .globl _clone _clone: /* Sanity check arguments. */ mov.l #-EINVAL,er3 mov.l er0,er0 /* no NULL function pointers */ beq __syscall_error mov.l er1,er1 /* no NULL stack pointers */ beq __syscall_error /* Allocate space and copy the argument onto the new stack. */ mov.l @(4:16,sp),er3 mov.l er3,@-er1 /* Do the system call */ mov.l er0,er3 /* er3 = child entry */ mov.l er1,er0 mov.l er2,er1 /* er1 = flags */ mov.l er0,er2 /* er2 = child sp */ mov.l #__NR_clone,r0 trapa #0 mov.l er0,er0 bmi __syscall_error beq thread_start rts __syscall_error: neg.l er0 mov.l er0,@-sp #if !defined(__PIC__) jsr @__errno_location #else mov.l @(__errno_location@GOTOFF,er5),er1 jsr @er1 #endif mov.l @sp,er1 mov.l er1,@er0 sub.l er0,er0 dec.l #1,er0 rts thread_start: mov.l @sp+,er0 /* restore args */ jsr @er3 mov.l er0,er1 mov.l #__NR_exit,er0 trapa #0