1*81621933Sguenther/* $OpenBSD: tfork_thread.S,v 1.5 2022/12/08 01:25:43 guenther Exp $ */ 2c6f64c6fSguenther 3c6f64c6fSguenther/* 4c6f64c6fSguenther * Copyright (c) 2005, Miodrag Vallat 5c6f64c6fSguenther * 6c6f64c6fSguenther * Redistribution and use in source and binary forms, with or without 7c6f64c6fSguenther * modification, are permitted provided that the following conditions 8c6f64c6fSguenther * are met: 9c6f64c6fSguenther * 1. Redistributions of source code must retain the above copyright 10c6f64c6fSguenther * notice, this list of conditions and the following disclaimer. 11c6f64c6fSguenther * 2. Redistributions in binary form must reproduce the above copyright 12c6f64c6fSguenther * notice, this list of conditions and the following disclaimer in the 13c6f64c6fSguenther * documentation and/or other materials provided with the distribution. 14c6f64c6fSguenther * 15c6f64c6fSguenther * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 16c6f64c6fSguenther * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 17c6f64c6fSguenther * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 18c6f64c6fSguenther * DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, 19c6f64c6fSguenther * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 20c6f64c6fSguenther * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR 21c6f64c6fSguenther * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22c6f64c6fSguenther * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, 23c6f64c6fSguenther * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN 24c6f64c6fSguenther * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 25c6f64c6fSguenther * POSSIBILITY OF SUCH DAMAGE. 26c6f64c6fSguenther */ 27c6f64c6fSguenther 28c6f64c6fSguenther#include "SYS.h" 29c6f64c6fSguenther 30c6f64c6fSguenther/* 3116b62b6aSguenther * int __tfork_thread(const struct __tfork *param, size_t psize, void (*func)(void *), void *arg); 32c6f64c6fSguenther */ 33c6f64c6fSguentherFRAMESZ=4*REGSZ 34c6f64c6fSguentherGPOFF=FRAMESZ-2*REGSZ 35c6f64c6fSguentherLEAF(__tfork_thread, FRAMESZ) 3616b62b6aSguenther /* a0 = param, a1 = psize, a2 = func, a3 = arg */ 37c6f64c6fSguenther PTR_SUBU sp, FRAMESZ 38*81621933Sguenther SETUP_GP64(GPOFF, __tfork_thread) 39c6f64c6fSguenther .set reorder 40c6f64c6fSguenther 41c6f64c6fSguenther move t1, a3 /* arg */ 42c6f64c6fSguenther 43c6f64c6fSguenther __DO_SYSCALL(__tfork) 44c6f64c6fSguenther bnez a3, 9f 45c6f64c6fSguenther 4616b62b6aSguenther beqz v0, 1f 4716b62b6aSguenther 48c6f64c6fSguenther RESTORE_GP64 49c6f64c6fSguenther PTR_ADDU sp, FRAMESZ 50c6f64c6fSguenther 51c6f64c6fSguenther /* 52c6f64c6fSguenther * In parent process: just return. 53c6f64c6fSguenther */ 54c6f64c6fSguenther j ra 55c6f64c6fSguenther 56c6f64c6fSguenther1: 57c6f64c6fSguenther /* 5816b62b6aSguenther * In child process: invoke function, then exit. 59c6f64c6fSguenther */ 60c6f64c6fSguenther 61c6f64c6fSguenther move t9, a2 /* func */ 62c6f64c6fSguenther move a0, t1 /* arg */ 63c6f64c6fSguenther move v0, zero 64c6f64c6fSguenther jal ra, t9 65c6f64c6fSguenther 66c6f64c6fSguenther move a0, zero 67c6f64c6fSguenther __DO_SYSCALL(__threxit) 6880466ddeSvisa teq zero, zero, 0x52 69c6f64c6fSguenther 70c6f64c6fSguenther9: 71c6f64c6fSguenther /* 72c6f64c6fSguenther * System call failure. 73c6f64c6fSguenther */ 74c6f64c6fSguenther LA t9, CERROR 75c6f64c6fSguenther 76c6f64c6fSguenther RESTORE_GP64 77c6f64c6fSguenther PTR_ADDU sp, FRAMESZ 78c6f64c6fSguenther jr t9 79c6f64c6fSguentherEND(__tfork_thread) 80