• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1/* Derived from: $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 <asm-generic/portability.h>
33#include <machine/asm.h>
34#include <machine/regnum.h>
35
36#include "jboffsets.h"
37
38/*
39 * setjmp, longjmp implementation for libc.
40 */
41
42FRAMESZ= MKFSIZ(2,6)
43A1OFF= FRAMESZ-4*REGSZ
44A0OFF= FRAMESZ-3*REGSZ
45GPOFF= FRAMESZ-2*REGSZ
46RAOFF= FRAMESZ-1*REGSZ
47
48#define FPREG64_S(FPR, OFF, BASE)       \
49        swc1    FPR, OFF(BASE)  ;       \
50        mfhc1   t0, FPR         ;       \
51        sw      t0, OFF+4(BASE) ;
52
53#define FPREG64_L(FPR, OFF, BASE)       \
54        lw      t0, OFF+4(BASE) ;       \
55        lw      t1, OFF(BASE)   ;       \
56        mtc1    t1, FPR         ;       \
57        mthc1   t0, FPR         ;       \
58
59
60
61NON_LEAF(WRAP(setjmp), FRAMESZ, ra)
62        .mask   0x80000000, RAOFF
63        PTR_SUBU sp, FRAMESZ                    # allocate stack frame
64        SETUP_GP64(GPOFF, WRAP(setjmp))
65        SAVE_GP(GPOFF)
66        .set    reorder
67        REG_S   ra, RAOFF(sp)                   # save state
68        REG_S   a0, A0OFF(sp)
69
70        move    a0, zero                        # get current signal mask
71        jal     sigblock
72
73        REG_L   v1, A0OFF(sp)                   # v1 = jmpbuf
74        REG_S   v0, JB_MASK(v1)                 # save sc_mask = sigblock(0)
75
76        REG_L   a0, A0OFF(sp)                   # restore jmpbuf
77        REG_L   ra, RAOFF(sp)
78        REG_S   ra, JB_PC(a0)                   # sc_pc = return address
79#if defined(__mips64)
80        dli     v0, MAGIC_SETJMP
81#else
82        li      v0, MAGIC_SETJMP
83#endif
84        REG_S   v0, JB_MAGIC(a0)
85        REG_S   s0, JB_S0(a0)
86        REG_S   s1, JB_S1(a0)
87        REG_S   s2, JB_S2(a0)
88        REG_S   s3, JB_S3(a0)
89        REG_S   s4, JB_S4(a0)
90        REG_S   s5, JB_S5(a0)
91        REG_S   s6, JB_S6(a0)
92        REG_S   s7, JB_S7(a0)
93        REG_S   s8, JB_S8(a0)
94        REG_L   v0, GPOFF(sp)
95        REG_S   v0, JB_GP(a0)
96        PTR_ADDU v0, sp, FRAMESZ
97        REG_S   v0, JB_SP(a0)
98
99#if !defined(SOFTFLOAT)
100        /*
101         * Would be nice if we could tell if the FP registers are currently being used.
102         * Assume they are, and use pointer to jmp_buf in a0 to save FP registers and the
103         * jmp_buf.fpused flag.
104         */
105        li      v0, 1                           # v0 = 1
106        REG_S   v0, JB_FPUSED(a0)               # a0->jb_fpused = v0:1
107        cfc1    v0, $31
108#if _MIPS_FPSET == 32
109        FPREG64_S($f20, JB_F20, a0)
110        FPREG64_S($f21, JB_F21, a0)
111        FPREG64_S($f22, JB_F22, a0)
112        FPREG64_S($f23, JB_F23, a0)
113        FPREG64_S($f24, JB_F24, a0)
114        FPREG64_S($f25, JB_F25, a0)
115        FPREG64_S($f26, JB_F26, a0)
116        FPREG64_S($f27, JB_F27, a0)
117        FPREG64_S($f28, JB_F28, a0)
118        FPREG64_S($f29, JB_F29, a0)
119        FPREG64_S($f30, JB_F30, a0)
120        FPREG64_S($f31, JB_F31, a0)
121#else
122        swc1    $f20, JB_F20(a0)
123        swc1    $f21, JB_F21(a0)
124        swc1    $f22, JB_F22(a0)
125        swc1    $f23, JB_F23(a0)
126        swc1    $f24, JB_F24(a0)
127        swc1    $f25, JB_F25(a0)
128        swc1    $f26, JB_F26(a0)
129        swc1    $f27, JB_F27(a0)
130        swc1    $f28, JB_F28(a0)
131        swc1    $f29, JB_F29(a0)
132        swc1    $f30, JB_F30(a0)
133        swc1    $f31, JB_F31(a0)
134#endif
135        REG_S   v0, JB_FSR(a0)
136#endif /* !SOFTFLOAT */
137        move    v0, zero
138        RESTORE_GP64
139        PTR_ADDU sp, FRAMESZ
140        j       ra
141
142botch:
143        jal     abort
144        RESTORE_GP64
145        PTR_ADDU sp, FRAMESZ
146END(WRAP(setjmp))
147
148
149LEAF(WRAP(longjmp), FRAMESZ)
150        PTR_SUBU sp, FRAMESZ
151        SETUP_GP64(GPOFF, WRAP(longjmp))
152        SAVE_GP(GPOFF)
153        .set    reorder
154        sw      a1, A1OFF(sp)
155        sw      a0, A0OFF(sp)
156
157        lw      a0, JB_MASK(a0)
158        jal     sigsetmask
159
160        lw      a0, A0OFF(sp)
161        lw      a1, A1OFF(sp)
162
163        .set    noreorder
164        REG_L   v0, JB_MAGIC(a0)
165        bne     v0, MAGIC_SETJMP, botch         # jump if error
166        REG_L   ra, JB_PC(a0)
167        REG_L   s0, JB_S0(a0)
168        REG_L   s1, JB_S1(a0)
169        REG_L   s2, JB_S2(a0)
170        REG_L   s3, JB_S3(a0)
171        REG_L   s4, JB_S4(a0)
172        REG_L   s5, JB_S5(a0)
173        REG_L   s6, JB_S6(a0)
174        REG_L   s7, JB_S7(a0)
175        REG_L   s8, JB_S8(a0)
176        REG_L   gp, JB_GP(a0)
177        REG_L   sp, JB_SP(a0)
178
179#if !defined(SOFTFLOAT)
180        REG_L   v0, JB_FSR(a0)
181        ctc1    v0, $31
182#if _MIPS_FPSET == 32
183        FPREG64_L($f20, JB_F20, a0)
184        FPREG64_L($f21, JB_F21, a0)
185        FPREG64_L($f22, JB_F22, a0)
186        FPREG64_L($f23, JB_F23, a0)
187        FPREG64_L($f24, JB_F24, a0)
188        FPREG64_L($f25, JB_F25, a0)
189        FPREG64_L($f26, JB_F26, a0)
190        FPREG64_L($f27, JB_F27, a0)
191        FPREG64_L($f28, JB_F28, a0)
192        FPREG64_L($f29, JB_F29, a0)
193        FPREG64_L($f30, JB_F30, a0)
194        FPREG64_L($f31, JB_F31, a0)
195#else
196        lwc1    $f20, JB_F20(a0)
197        lwc1    $f21, JB_F21(a0)
198        lwc1    $f22, JB_F22(a0)
199        lwc1    $f23, JB_F23(a0)
200        lwc1    $f24, JB_F24(a0)
201        lwc1    $f25, JB_F25(a0)
202        lwc1    $f26, JB_F26(a0)
203        lwc1    $f27, JB_F27(a0)
204        lwc1    $f28, JB_F28(a0)
205        lwc1    $f29, JB_F29(a0)
206        lwc1    $f30, JB_F30(a0)
207        lwc1    $f31, JB_F31(a0)
208#endif
209#endif /* !SOFTFLOAT */
210        bne     a1, zero, 1f
211         nop
212        li      a1, 1                   # never return 0!
2131:
214        j       ra
215         move   v0, a1
216
217END(WRAP(longjmp))
218