root/lib/libc/arch/powerpc/sys/tfork_thread.S
/*      $OpenBSD: tfork_thread.S,v 1.11 2023/12/10 16:45:51 deraadt Exp $       */

/*
 * Copyright (c) 2005 Tim Wiess <tim@nop.cx>
 *
 * Permission to use, copy, modify, and distribute this software for any
 * purpose with or without fee is hereby granted, provided that the above
 * copyright notice and this permission notice appear in all copies.
 *
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
 */

#include "SYS.h"

ENTRY(__tfork_thread)
        RETGUARD_SETUP(__tfork_thread, %r11, %r12)
        /* call __tfork */
        li      %r0, SYS___tfork
99:     sc
        PINSYSCALL(SYS___tfork, 99b)
        cmpwi   %r0, 0
        bne     1f
        
        /* check if we are parent or child */
        cmpwi   %r3, 0
        bne     9f
        
        /* child */
        mtlr    %r5             /* fp */
        mr      %r3, %r6        /* arg */
        subi    %r1, %r1, 16    /* fixup sp to get headroom */
        blrl
        
        /* child returned, call __threxit */
        li      %r0, SYS___threxit
98:     sc
        PINSYSCALL(SYS___threxit, 98b)
        .long   0               /* illegal */

1:
        stw     0, R2_OFFSET_ERRNO(%r2)
        li      %r3, -1
9:
        RETGUARD_CHECK(__tfork_thread, %r11, %r12)
        blr
END(__tfork_thread)