1*252fbae2Sskrll/* $NetBSD: compat_setjmp.S,v 1.5 2020/10/15 05:27:53 skrll Exp $ */ 2f80595caStsutsui 3f80595caStsutsui/*- 4f80595caStsutsui * Copyright (c) 1991, 1993 5f80595caStsutsui * The Regents of the University of California. All rights reserved. 6f80595caStsutsui * 7f80595caStsutsui * This code is derived from software contributed to Berkeley by 8f80595caStsutsui * Ralph Campbell. 9f80595caStsutsui * 10f80595caStsutsui * Redistribution and use in source and binary forms, with or without 11f80595caStsutsui * modification, are permitted provided that the following conditions 12f80595caStsutsui * are met: 13f80595caStsutsui * 1. Redistributions of source code must retain the above copyright 14f80595caStsutsui * notice, this list of conditions and the following disclaimer. 15f80595caStsutsui * 2. Redistributions in binary form must reproduce the above copyright 16f80595caStsutsui * notice, this list of conditions and the following disclaimer in the 17f80595caStsutsui * documentation and/or other materials provided with the distribution. 18f80595caStsutsui * 3. Neither the name of the University nor the names of its contributors 19f80595caStsutsui * may be used to endorse or promote products derived from this software 20f80595caStsutsui * without specific prior written permission. 21f80595caStsutsui * 22f80595caStsutsui * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 23f80595caStsutsui * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 24f80595caStsutsui * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 25f80595caStsutsui * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 26f80595caStsutsui * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 27f80595caStsutsui * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 28f80595caStsutsui * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 29f80595caStsutsui * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 30f80595caStsutsui * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31f80595caStsutsui * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32f80595caStsutsui * SUCH DAMAGE. 33f80595caStsutsui */ 34f80595caStsutsui 35f80595caStsutsui#include <sys/syscall.h> 36f80595caStsutsui#include <mips/asm.h> 37f45a8c29Smatt 38f45a8c29Smatt#include "assym.h" 39f80595caStsutsui 40f80595caStsutsui#if defined(LIBC_SCCS) && !defined(lint) 41f45a8c29Smatt#if 0 42f45a8c29Smatt RCSID("from: @(#)setjmp.s 8.1 (Berkeley) 6/4/93") 43f45a8c29Smatt#else 44*252fbae2Sskrll RCSID("$NetBSD: compat_setjmp.S,v 1.5 2020/10/15 05:27:53 skrll Exp $") 45f80595caStsutsui#endif 46f45a8c29Smatt#endif /* LIBC_SCCS and not lint */ 47f80595caStsutsui 48f80595caStsutsui/* 49f80595caStsutsui * C library -- setjmp, longjmp 50f80595caStsutsui * 51f80595caStsutsui * longjmp(a,v) 52f80595caStsutsui * will generate a "return(v)" from 53f80595caStsutsui * the last call to 54f80595caStsutsui * setjmp(a) 55f80595caStsutsui * by restoring registers from the stack, 56f80595caStsutsui * and a struct sigcontext, see <signal.h> 57f80595caStsutsui */ 58f80595caStsutsui 59f45a8c29Smatt#define SETJMP_FRAME_SIZE (CALLFRAME_SIZ + STACK_T_SIZE) 60f80595caStsutsui 61f80595caStsutsuiNON_LEAF(setjmp, SETJMP_FRAME_SIZE, ra) 62f45a8c29Smatt .mask 0x80010000, (CALLFRAME_RA - CALLFRAME_SIZ) 63f45a8c29Smatt SETUP_GP 64f45a8c29Smatt PTR_SUBU sp, sp, SETJMP_FRAME_SIZE # allocate stack frame 65f45a8c29Smatt SAVE_GP(CALLFRAME_GP) 66f45a8c29Smatt SETUP_GP64(CALLFRAME_GP, setjmp) 67f45a8c29Smatt 68f45a8c29Smatt REG_S ra, CALLFRAME_RA(sp) # save RA 69f45a8c29Smatt REG_S s0, CALLFRAME_S0(sp) # save S0 70f45a8c29Smatt move s0, a0 # save sigcontext 71f45a8c29Smatt 72f45a8c29Smatt /* Get the signal mask. */ 73f45a8c29Smatt move a0, zero # get current sigmask 74f80595caStsutsui jal _C_LABEL(sigblock) 75f45a8c29Smatt nop 76*252fbae2Sskrll INT_S v0, _SC_MASK13(s0) # save sc_mask13 77f45a8c29Smatt 78f45a8c29Smatt /* Get the signal stack. */ 79f80595caStsutsui move a0, zero 80f45a8c29Smatt PTR_ADDU a1, sp, CALLFRAME_SIZ # pointer to stack_t 81f80595caStsutsui jal _C_LABEL(__sigaltstack14) 82f45a8c29Smatt 83f45a8c29Smatt move a0, s0 # restore jmpbuf 84*252fbae2Sskrll INT_L v1, CALLFRAME_SIZ+_STACK_T_FLAGS(sp) 85f45a8c29Smatt # get old ss_onstack 86f45a8c29Smatt and v1, v1, SS_ONSTACK # extract onstack flag 87*252fbae2Sskrll INT_S v1, _SC_ONSTACK(a0) # save it in sc_onstack 88f45a8c29Smatt 89f45a8c29Smatt REG_L s0, CALLFRAME_S0(sp) # restore S0 90f45a8c29Smatt REG_L ra, CALLFRAME_RA(sp) # restore RA 91f45a8c29Smatt blt v0, zero, botch # check for sigaltstack() error 92f45a8c29Smatt nop 93f45a8c29Smatt /* 94f45a8c29Smatt * We know we won't need this routine's GP anymore. 95f45a8c29Smatt */ 96f45a8c29Smatt RESTORE_GP64 97f45a8c29Smatt PTR_ADDU sp, sp, SETJMP_FRAME_SIZE # pop stack frame 98f45a8c29Smatt 99f80595caStsutsui REG_PROLOGUE 100*252fbae2Sskrll REG_S ra, _SC_PC(a0) # sc_pc = return address 101f80595caStsutsui REG_LI v0, 0xACEDBADE # sigcontext magic number 102*252fbae2Sskrll REG_S v0, _SC_REGS(a0) # saved in sc_regs[0] 103*252fbae2Sskrll REG_S s0, _SC_REGS_S0(a0) 104*252fbae2Sskrll REG_S s1, _SC_REGS_S1(a0) 105*252fbae2Sskrll REG_S s2, _SC_REGS_S2(a0) 106*252fbae2Sskrll REG_S s3, _SC_REGS_S3(a0) 107*252fbae2Sskrll REG_S s4, _SC_REGS_S4(a0) 108*252fbae2Sskrll REG_S s5, _SC_REGS_S5(a0) 109*252fbae2Sskrll REG_S s6, _SC_REGS_S6(a0) 110*252fbae2Sskrll REG_S s7, _SC_REGS_S7(a0) 111*252fbae2Sskrll REG_S gp, _SC_REGS_GP(a0) 112*252fbae2Sskrll REG_S sp, _SC_REGS_SP(a0) 113*252fbae2Sskrll REG_S s8, _SC_REGS_S8(a0) 1141d939007Smartin#ifdef SOFTFLOAT_FOR_GCC 115*252fbae2Sskrll INT_S zero, _SC_FPUSED(a0) # sc_fpused = 0 1161d939007Smartin#else 117f80595caStsutsui li v0, 1 # be nice if we could tell 118*252fbae2Sskrll INT_S v0, _SC_FPUSED(a0) # sc_fpused = 1 119f80595caStsutsui cfc1 v0, $31 120*252fbae2Sskrll INT_S v0, _SC_FPREGS_FCSR(a0) 121f45a8c29Smatt#if defined(__mips_o32) || defined(__mips_o64) || defined(__mips_n32) 122*252fbae2Sskrll FP_S $f20, _SC_FPREGS_F20(a0) 123*252fbae2Sskrll FP_S $f22, _SC_FPREGS_F22(a0) 124f45a8c29Smatt#endif 125f45a8c29Smatt#if defined(__mips_o32) || defined(__mips_o64) 126*252fbae2Sskrll FP_S $f21, _SC_FPREGS_F21(a0) 127*252fbae2Sskrll FP_S $f23, _SC_FPREGS_F23(a0) 128f45a8c29Smatt#endif 129f45a8c29Smatt#if defined(__mips_n32) || defined(__mips_n64) 130*252fbae2Sskrll FP_S $f24, _SC_FPREGS_F24(a0) 131*252fbae2Sskrll FP_S $f26, _SC_FPREGS_F26(a0) 132*252fbae2Sskrll FP_S $f28, _SC_FPREGS_F28(a0) 133*252fbae2Sskrll FP_S $f30, _SC_FPREGS_F30(a0) 134f45a8c29Smatt#endif 135f45a8c29Smatt#if defined(__mips_n64) 136*252fbae2Sskrll FP_S $f25, _SC_FPREGS_F25(a0) 137*252fbae2Sskrll FP_S $f27, _SC_FPREGS_F27(a0) 138*252fbae2Sskrll FP_S $f29, _SC_FPREGS_F29(a0) 139*252fbae2Sskrll FP_S $f31, _SC_FPREGS_F31(a0) 140f45a8c29Smatt#endif 1411d939007Smartin#endif /* SOFTFLOAT_FOR_GCC */ 142f80595caStsutsui REG_EPILOGUE 143f80595caStsutsui j ra 144f45a8c29Smatt move v0, zero 145f45a8c29Smatt 146f45a8c29Smattbotch: 147f45a8c29Smatt jal _C_LABEL(abort) 148f80595caStsutsuiEND(setjmp) 149f80595caStsutsui 150f80595caStsutsuiLEAF(longjmp) 151f45a8c29Smatt SETUP_GP 152f45a8c29Smatt PTR_SUBU sp, sp, CALLFRAME_SIZ 153f45a8c29Smatt SAVE_GP(CALLFRAME_S0) 154f45a8c29Smatt SETUP_GP64(s0, longjmp) 155f45a8c29Smatt 156f80595caStsutsui REG_PROLOGUE 157f80595caStsutsui /* save return value in sc_regs[_R_V0] */ 158*252fbae2Sskrll REG_S a1, _SC_REGS_V0(a0) 159f80595caStsutsui REG_EPILOGUE 160f45a8c29Smatt 161f80595caStsutsui li v0, SYS_compat_13_sigreturn13 162f80595caStsutsui syscall 163f45a8c29Smatt 164f80595caStsutsui jal _C_LABEL(longjmperror) 165f80595caStsutsui jal _C_LABEL(abort) 166f80595caStsutsuiEND(longjmp) 167