1 /* Derived from: $OpenBSD: _setjmp.S,v 1.4 2005/08/07 16:40:15 espie Exp $ */ 2 3 /* 4 * Copyright (c) 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 <asm-generic/portability.h> 33 #include <machine/asm.h> 34 #include <machine/regnum.h> 35 36 #include "jboffsets.h" 37 38 /* 39 * _setjmp, _longjmp (not restoring signal state) 40 * 41 * XXX FPSET should probably be taken from SR setting. hmmm... 42 * GPOFF and FRAMESIZE must be the same for both _setjmp and _longjmp! 43 * 44 */ 45 46 FRAMESZ= MKFSIZ(0,4) 47 GPOFF= FRAMESZ-2*REGSZ 48 49 #define FPREG64_S(FPR, OFF, BASE) \ 50 swc1 FPR, OFF(BASE) ; \ 51 mfhc1 t0, FPR ; \ 52 sw t0, OFF+4(BASE) ; 53 54 #define FPREG64_L(FPR, OFF, BASE) \ 55 lw t0, OFF+4(BASE) ; \ 56 lw t1, OFF(BASE) ; \ 57 mtc1 t1, FPR ; \ 58 mthc1 t0, FPR ; \ 59 60 LEAF(_setjmp_portable, FRAMESZ) 61 PTR_SUBU sp, FRAMESZ 62 SETUP_GP64(GPOFF, _setjmp) 63 SAVE_GP(GPOFF) 64 .set noreorder 65 #if defined(__mips64) 66 dli v0, MAGIC__SETJMP 67 #else 68 li v0, MAGIC__SETJMP 69 #endif 70 REG_S v0, JB_MAGIC(a0) 71 REG_S s0, JB_S0(a0) 72 REG_S s1, JB_S1(a0) 73 REG_S s2, JB_S2(a0) 74 REG_S s3, JB_S3(a0) 75 REG_S s4, JB_S4(a0) 76 REG_S s5, JB_S5(a0) 77 REG_S s6, JB_S6(a0) 78 REG_S s7, JB_S7(a0) 79 REG_S s8, JB_S8(a0) 80 REG_L v0, GPOFF(sp) 81 REG_S v0, JB_GP(a0) 82 PTR_ADDU v0, sp, FRAMESZ 83 REG_S v0, JB_SP(a0) 84 REG_S ra, JB_PC(a0) 85 86 #if !defined(SOFTFLOAT) 87 /* 88 * Would be nice if we could tell if the FP registers are currently being used; 89 * Assume they are, and use pointer to jmp_buf in a0 to save FP registers and the 90 * jmp_buf.fpused flag. 91 */ 92 li v0, 1 # v0 = 1 93 REG_S v0, JB_FPUSED(a0) # a0->jb_fpused = v0:1 94 cfc1 v0, $31 95 #if _MIPS_FPSET == 32 96 FPREG64_S($f20, JB_F20, a0) 97 FPREG64_S($f21, JB_F21, a0) 98 FPREG64_S($f22, JB_F22, a0) 99 FPREG64_S($f23, JB_F23, a0) 100 FPREG64_S($f24, JB_F24, a0) 101 FPREG64_S($f25, JB_F25, a0) 102 FPREG64_S($f26, JB_F26, a0) 103 FPREG64_S($f27, JB_F27, a0) 104 FPREG64_S($f28, JB_F28, a0) 105 FPREG64_S($f29, JB_F29, a0) 106 FPREG64_S($f30, JB_F30, a0) 107 FPREG64_S($f31, JB_F31, a0) 108 #else 109 swc1 $f20, JB_F20(a0) 110 swc1 $f21, JB_F21(a0) 111 swc1 $f22, JB_F22(a0) 112 swc1 $f23, JB_F23(a0) 113 swc1 $f24, JB_F24(a0) 114 swc1 $f25, JB_F25(a0) 115 swc1 $f26, JB_F26(a0) 116 swc1 $f27, JB_F27(a0) 117 swc1 $f28, JB_F28(a0) 118 swc1 $f29, JB_F29(a0) 119 swc1 $f30, JB_F30(a0) 120 swc1 $f31, JB_F31(a0) 121 #endif 122 REG_S v0, JB_FSR(a0) 123 #endif /* !SOFTFLOAT */ 124 RESTORE_GP64 125 PTR_ADDU sp, FRAMESZ 126 j ra 127 move v0, zero 128 END(_setjmp_portable) 129 130 LEAF(_longjmp_portable, FRAMESZ) 131 PTR_SUBU sp, FRAMESZ 132 SETUP_GP64(GPOFF, _longjmp) 133 SAVE_GP(GPOFF) 134 .set noreorder 135 REG_L v0, JB_MAGIC(a0) 136 bne v0, MAGIC__SETJMP, botch # jump if error 137 REG_L ra, JB_PC(a0) 138 REG_L v0, JB_FSR(a0) 139 REG_L s0, JB_S0(a0) 140 REG_L s1, JB_S1(a0) 141 REG_L s2, JB_S2(a0) 142 REG_L s3, JB_S3(a0) 143 REG_L s4, JB_S4(a0) 144 REG_L s5, JB_S5(a0) 145 REG_L s6, JB_S6(a0) 146 REG_L s7, JB_S7(a0) 147 REG_L s8, JB_S8(a0) 148 REG_L gp, JB_GP(a0) 149 REG_L sp, JB_SP(a0) 150 #if !defined(SOFTFLOAT) 151 ctc1 v0, $31 152 #if _MIPS_FPSET == 32 153 FPREG64_L($f20, JB_F20, a0) 154 FPREG64_L($f21, JB_F21, a0) 155 FPREG64_L($f22, JB_F22, a0) 156 FPREG64_L($f23, JB_F23, a0) 157 FPREG64_L($f24, JB_F24, a0) 158 FPREG64_L($f25, JB_F25, a0) 159 FPREG64_L($f26, JB_F26, a0) 160 FPREG64_L($f27, JB_F27, a0) 161 FPREG64_L($f28, JB_F28, a0) 162 FPREG64_L($f29, JB_F29, a0) 163 FPREG64_L($f30, JB_F30, a0) 164 FPREG64_L($f31, JB_F31, a0) 165 #else 166 lwc1 $f20, JB_F20(a0) 167 lwc1 $f21, JB_F21(a0) 168 lwc1 $f22, JB_F22(a0) 169 lwc1 $f23, JB_F23(a0) 170 lwc1 $f24, JB_F24(a0) 171 lwc1 $f25, JB_F25(a0) 172 lwc1 $f26, JB_F26(a0) 173 lwc1 $f27, JB_F27(a0) 174 lwc1 $f28, JB_F28(a0) 175 lwc1 $f29, JB_F29(a0) 176 lwc1 $f30, JB_F30(a0) 177 lwc1 $f31, JB_F31(a0) 178 #endif 179 #endif /* !SOFTFLOAT */ 180 bne a1, zero, 1f 181 nop 182 li a1, 1 # never return 0! 183 1: 184 j ra 185 move v0, a1 186 187 botch: 188 jal abort 189 nop 190 RESTORE_GP64 191 PTR_ADDU sp, FRAMESZ 192 END(_longjmp_portable) 193