blob: 2af1fbdce39b84a6222c1056448979513af56519 [file] [log] [blame]
Raghu Gandham405b8022012-07-25 18:16:42 -07001/* $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
Elliott Hughes851e68a2014-02-19 16:53:20 -080032#include <private/bionic_asm.h>
Raghu Gandham405b8022012-07-25 18:16:42 -070033#include <machine/regnum.h>
David 'Digit' Turnerc1b44ec2012-10-17 19:10:11 +020034#include <machine/signal.h>
Raghu Gandham405b8022012-07-25 18:16:42 -070035
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
48#define FPREG64_S(FPR, OFF, BASE) \
49 swc1 FPR, OFF(BASE) ; \
50 mfhc1 t0, FPR ; \
51 sw t0, OFF+4(BASE) ;
Elliott Hughes851e68a2014-02-19 16:53:20 -080052
Raghu Gandham405b8022012-07-25 18:16:42 -070053#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 ; \
Elliott Hughes851e68a2014-02-19 16:53:20 -080058
Raghu Gandham405b8022012-07-25 18:16:42 -070059NON_LEAF(setjmp, FRAMESZ, ra)
60 .mask 0x80000000, RAOFF
61 PTR_SUBU sp, FRAMESZ # allocate stack frame
62 SETUP_GP64(GPOFF, setjmp)
63 SAVE_GP(GPOFF)
64 .set reorder
65 REG_S ra, RAOFF(sp) # save state
66 REG_S a0, A0OFF(sp)
67
68 move a0, zero # get current signal mask
69 jal sigblock
70
71 REG_L v1, A0OFF(sp) # v1 = jmpbuf
72 REG_S v0, SC_MASK(v1) # save sc_mask = sigblock(0)
73
74 REG_L a0, A0OFF(sp) # restore jmpbuf
75 REG_L ra, RAOFF(sp)
76 REG_S ra, SC_PC(a0) # sc_pc = return address
77#if defined(__mips64)
78 dli v0, 0xACEDBADE # sigcontext magic number
79#else
80 li v0, 0xACEDBADE # sigcontext magic number
81#endif
82 REG_S v0, SC_REGS+ZERO*REGSZ(a0)
83 REG_S s0, SC_REGS+S0*REGSZ(a0)
84 REG_S s1, SC_REGS+S1*REGSZ(a0)
85 REG_S s2, SC_REGS+S2*REGSZ(a0)
86 REG_S s3, SC_REGS+S3*REGSZ(a0)
87 REG_S s4, SC_REGS+S4*REGSZ(a0)
88 REG_S s5, SC_REGS+S5*REGSZ(a0)
89 REG_S s6, SC_REGS+S6*REGSZ(a0)
90 REG_S s7, SC_REGS+S7*REGSZ(a0)
91 REG_S s8, SC_REGS+S8*REGSZ(a0)
92 REG_L v0, GPOFF(sp)
93 REG_S v0, SC_REGS+GP*REGSZ(a0)
94 PTR_ADDU v0, sp, FRAMESZ
95 REG_S v0, SC_REGS+SP*REGSZ(a0)
96
97#if !defined(SOFTFLOAT)
98 li v0, 1 # be nice if we could tell
99 REG_S v0, SC_FPUSED(a0) # sc_fpused = 1
100 cfc1 v0, $31
101#if _MIPS_FPSET == 32
102 FPREG64_S($f20, SC_FPREGS+((F20-F0)*REGSZ_FP), a0)
103 FPREG64_S($f21, SC_FPREGS+((F21-F0)*REGSZ_FP), a0)
104 FPREG64_S($f22, SC_FPREGS+((F22-F0)*REGSZ_FP), a0)
105 FPREG64_S($f23, SC_FPREGS+((F23-F0)*REGSZ_FP), a0)
106 FPREG64_S($f24, SC_FPREGS+((F24-F0)*REGSZ_FP), a0)
107 FPREG64_S($f25, SC_FPREGS+((F25-F0)*REGSZ_FP), a0)
108 FPREG64_S($f26, SC_FPREGS+((F26-F0)*REGSZ_FP), a0)
109 FPREG64_S($f27, SC_FPREGS+((F27-F0)*REGSZ_FP), a0)
110 FPREG64_S($f28, SC_FPREGS+((F28-F0)*REGSZ_FP), a0)
111 FPREG64_S($f29, SC_FPREGS+((F29-F0)*REGSZ_FP), a0)
112 FPREG64_S($f30, SC_FPREGS+((F30-F0)*REGSZ_FP), a0)
113 FPREG64_S($f31, SC_FPREGS+((F31-F0)*REGSZ_FP), a0)
114#else
115 swc1 $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
116 swc1 $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
117 swc1 $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
118 swc1 $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
119 swc1 $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
120 swc1 $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
121 swc1 $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
122 swc1 $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
123 swc1 $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
124 swc1 $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
125 swc1 $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
126 swc1 $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
127#endif
128 REG_S v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
129#endif /* !SOFTFLOAT */
130 move v0, zero
131 RESTORE_GP64
132 PTR_ADDU sp, FRAMESZ
133 j ra
134
135botch:
136 jal longjmperror
137 jal abort
138 RESTORE_GP64
139 PTR_ADDU sp, FRAMESZ
140END(setjmp)
141
142
143LEAF(longjmp, FRAMESZ)
144 PTR_SUBU sp, FRAMESZ
145 SETUP_GP64(GPOFF, longjmp)
146 SAVE_GP(GPOFF)
147 .set reorder
148 sw a1, A1OFF(sp)
149 sw a0, A0OFF(sp)
150
151 lw a0, SC_MASK(a0)
152 jal sigsetmask
153
154 lw a0, A0OFF(sp)
155 lw a1, A1OFF(sp)
156
Elliott Hughes851e68a2014-02-19 16:53:20 -0800157 .set noreorder
Raghu Gandham405b8022012-07-25 18:16:42 -0700158 REG_L v0, SC_REGS+ZERO*REGSZ(a0)
159 bne v0, 0xACEDBADE, botch # jump if error
160 REG_L ra, SC_PC(a0)
161 REG_L s0, SC_REGS+S0*REGSZ(a0)
162 REG_L s1, SC_REGS+S1*REGSZ(a0)
163 REG_L s2, SC_REGS+S2*REGSZ(a0)
164 REG_L s3, SC_REGS+S3*REGSZ(a0)
165 REG_L s4, SC_REGS+S4*REGSZ(a0)
166 REG_L s5, SC_REGS+S5*REGSZ(a0)
167 REG_L s6, SC_REGS+S6*REGSZ(a0)
168 REG_L s7, SC_REGS+S7*REGSZ(a0)
169 REG_L s8, SC_REGS+S8*REGSZ(a0)
170 REG_L gp, SC_REGS+GP*REGSZ(a0)
171 REG_L sp, SC_REGS+SP*REGSZ(a0)
Elliott Hughes851e68a2014-02-19 16:53:20 -0800172
Raghu Gandham405b8022012-07-25 18:16:42 -0700173#if !defined(SOFTFLOAT)
Elliott Hughes851e68a2014-02-19 16:53:20 -0800174 REG_L v0, SC_FPREGS+((FSR-F0)*REGSZ)(a0)
Raghu Gandham405b8022012-07-25 18:16:42 -0700175 ctc1 v0, $31
176#if _MIPS_FPSET == 32
177 FPREG64_L($f20, SC_FPREGS+((F20-F0)*REGSZ_FP), a0)
178 FPREG64_L($f21, SC_FPREGS+((F21-F0)*REGSZ_FP), a0)
179 FPREG64_L($f22, SC_FPREGS+((F22-F0)*REGSZ_FP), a0)
180 FPREG64_L($f23, SC_FPREGS+((F23-F0)*REGSZ_FP), a0)
181 FPREG64_L($f24, SC_FPREGS+((F24-F0)*REGSZ_FP), a0)
182 FPREG64_L($f25, SC_FPREGS+((F25-F0)*REGSZ_FP), a0)
183 FPREG64_L($f26, SC_FPREGS+((F26-F0)*REGSZ_FP), a0)
184 FPREG64_L($f27, SC_FPREGS+((F27-F0)*REGSZ_FP), a0)
185 FPREG64_L($f28, SC_FPREGS+((F28-F0)*REGSZ_FP), a0)
186 FPREG64_L($f29, SC_FPREGS+((F29-F0)*REGSZ_FP), a0)
187 FPREG64_L($f30, SC_FPREGS+((F30-F0)*REGSZ_FP), a0)
188 FPREG64_L($f31, SC_FPREGS+((F31-F0)*REGSZ_FP), a0)
189#else
190 lwc1 $f20, SC_FPREGS+((F20-F0)*REGSZ_FP)(a0)
191 lwc1 $f21, SC_FPREGS+((F21-F0)*REGSZ_FP)(a0)
192 lwc1 $f22, SC_FPREGS+((F22-F0)*REGSZ_FP)(a0)
193 lwc1 $f23, SC_FPREGS+((F23-F0)*REGSZ_FP)(a0)
194 lwc1 $f24, SC_FPREGS+((F24-F0)*REGSZ_FP)(a0)
195 lwc1 $f25, SC_FPREGS+((F25-F0)*REGSZ_FP)(a0)
196 lwc1 $f26, SC_FPREGS+((F26-F0)*REGSZ_FP)(a0)
197 lwc1 $f27, SC_FPREGS+((F27-F0)*REGSZ_FP)(a0)
198 lwc1 $f28, SC_FPREGS+((F28-F0)*REGSZ_FP)(a0)
199 lwc1 $f29, SC_FPREGS+((F29-F0)*REGSZ_FP)(a0)
200 lwc1 $f30, SC_FPREGS+((F30-F0)*REGSZ_FP)(a0)
201 lwc1 $f31, SC_FPREGS+((F31-F0)*REGSZ_FP)(a0)
202#endif
203#endif /* !SOFTFLOAT */
204 bne a1, zero, 1f
205 nop
206 li a1, 1 # never return 0!
2071:
208 j ra
209 move v0, a1
210
211END(longjmp)