1/* $OpenBSD: setjmp.S,v 1.5 2005/08/07 16:40:15 espie Exp $ */ 2 3/* 4 * Copyright (c) 2001-2002 Opsycon AB (www.opsycon.se / www.opsycon.com) 5 * 6 * Redistribution and use in source and binary forms, with or without 7 * modification, are permitted provided that the following conditions 8 * are met: 9 * 1. Redistributions of source code must retain the above copyright 10 * notice, this list of conditions and the following disclaimer. 11 * 2. Redistributions in binary form must reproduce the above copyright 12 * notice, this list of conditions and the following disclaimer in the 13 * documentation and/or other materials provided with the distribution. 14 * 3. Neither the name of Opsycon AB nor the names of its contributors 15 * may be used to endorse or promote products derived from this software 16 * without specific prior written permission. 17 * 18 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS 19 * OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 20 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 21 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY 22 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 23 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 24 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 25 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 26 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 27 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 28 * SUCH DAMAGE. 29 * 30 */ 31 32#include <private/bionic_asm.h> 33#include <machine/regnum.h> 34#include <machine/signal.h> 35 36/* 37 * setjmp, longjmp implementation for libc. this code depends 38 * on the layout of the struct sigcontext in machine/signal.h. 39 * 40 */ 41 42FRAMESZ= MKFSIZ(2,6) 43A1OFF= FRAMESZ-4*REGSZ 44A0OFF= FRAMESZ-3*REGSZ 45GPOFF= FRAMESZ-2*REGSZ 46RAOFF= FRAMESZ-1*REGSZ 47 48NON_LEAF(setjmp, FRAMESZ, ra) 49 .mask 0x80000000, RAOFF 50 PTR_SUBU sp, FRAMESZ # allocate stack frame 51 SETUP_GP64(GPOFF, setjmp) 52 SAVE_GP(GPOFF) 53 .set reorder 54 REG_S ra, RAOFF(sp) # save state 55 REG_S a0, A0OFF(sp) 56 57 move a0, zero # get current signal mask 58 jal sigblock 59 60 REG_L v1, A0OFF(sp) # v1 = jmpbuf 61 REG_S v0, SC_MASK(v1) # save sc_mask = sigblock(0) 62 63 REG_L a0, A0OFF(sp) # restore jmpbuf 64 REG_L ra, RAOFF(sp) 65 REG_S ra, SC_PC(a0) # sc_pc = return address 66#if defined(__mips64) 67 dli v0, 0xACEDBADE # sigcontext magic number 68#else 69 li v0, 0xACEDBADE # sigcontext magic number 70#endif 71 REG_S v0, SC_REGS+ZERO*REGSZ(a0) 72 REG_S s0, SC_REGS+S0*REGSZ(a0) 73 REG_S s1, SC_REGS+S1*REGSZ(a0) 74 REG_S s2, SC_REGS+S2*REGSZ(a0) 75 REG_S s3, SC_REGS+S3*REGSZ(a0) 76 REG_S s4, SC_REGS+S4*REGSZ(a0) 77 REG_S s5, SC_REGS+S5*REGSZ(a0) 78 REG_S s6, SC_REGS+S6*REGSZ(a0) 79 REG_S s7, SC_REGS+S7*REGSZ(a0) 80 REG_S s8, SC_REGS+S8*REGSZ(a0) 81 REG_L v0, GPOFF(sp) 82 REG_S v0, SC_REGS+GP*REGSZ(a0) 83 PTR_ADDU v0, sp, FRAMESZ 84 REG_S v0, SC_REGS+SP*REGSZ(a0) 85 86#if !defined(SOFTFLOAT) 87 li v0, 1 # be nice if we could tell 88 REG_S v0, SC_FPUSED(a0) # sc_fpused = 1 89 cfc1 v0, $31 90 s.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) 91 s.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) 92 s.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) 93 s.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) 94 s.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) 95 s.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) 96#if _MIPS_FPSET == 32 97 s.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) 98 s.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) 99 s.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) 100 s.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) 101 s.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) 102 s.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) 103#endif 104 REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) 105#endif /* !SOFTFLOAT */ 106 move v0, zero 107 RESTORE_GP64 108 PTR_ADDU sp, FRAMESZ 109 j ra 110 111botch: 112 jal longjmperror 113 jal abort 114 RESTORE_GP64 115 PTR_ADDU sp, FRAMESZ 116END(setjmp) 117 118 119LEAF(longjmp, FRAMESZ) 120 PTR_SUBU sp, FRAMESZ 121 SETUP_GP64(GPOFF, longjmp) 122 SAVE_GP(GPOFF) 123 .set reorder 124 sw a1, A1OFF(sp) 125 sw a0, A0OFF(sp) 126 127 lw a0, SC_MASK(a0) 128 jal sigsetmask 129 130 lw a0, A0OFF(sp) 131 lw a1, A1OFF(sp) 132 133 .set noreorder 134 REG_L v0, SC_REGS+ZERO*REGSZ(a0) 135 bne v0, 0xACEDBADE, botch # jump if error 136 REG_L ra, SC_PC(a0) 137 REG_L s0, SC_REGS+S0*REGSZ(a0) 138 REG_L s1, SC_REGS+S1*REGSZ(a0) 139 REG_L s2, SC_REGS+S2*REGSZ(a0) 140 REG_L s3, SC_REGS+S3*REGSZ(a0) 141 REG_L s4, SC_REGS+S4*REGSZ(a0) 142 REG_L s5, SC_REGS+S5*REGSZ(a0) 143 REG_L s6, SC_REGS+S6*REGSZ(a0) 144 REG_L s7, SC_REGS+S7*REGSZ(a0) 145 REG_L s8, SC_REGS+S8*REGSZ(a0) 146 REG_L gp, SC_REGS+GP*REGSZ(a0) 147 REG_L sp, SC_REGS+SP*REGSZ(a0) 148 149#if !defined(SOFTFLOAT) 150 REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0) 151 ctc1 v0, $31 152 l.d $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0) 153 l.d $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0) 154 l.d $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0) 155 l.d $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0) 156 l.d $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0) 157 l.d $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0) 158#if _MIPS_FPSET == 32 159 l.d $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0) 160 l.d $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0) 161 l.d $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0) 162 l.d $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0) 163 l.d $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0) 164 l.d $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0) 165#endif 166#endif /* !SOFTFLOAT */ 167 bne a1, zero, 1f 168 nop 169 li a1, 1 # never return 0! 1701: 171 j ra 172 move v0, a1 173 174END(longjmp) 175