blob: 81a1a538a69a88071036beaf060eb35f5f97b839 [file] [log] [blame]
sewardj6c591e12011-04-11 16:17:51 +00001
2/*--------------------------------------------------------------------*/
3/*--- A minimal setjmp/longjmp implementation. m_libcsetjmp.c ---*/
4/*--------------------------------------------------------------------*/
5
6/*
7 This file is part of Valgrind, a dynamic binary instrumentation
8 framework.
9
sewardjb3a1e4b2015-08-21 11:32:26 +000010 Copyright (C) 2010-2015 Mozilla Inc
sewardj6c591e12011-04-11 16:17:51 +000011
12 This program is free software; you can redistribute it and/or
13 modify it under the terms of the GNU General Public License as
14 published by the Free Software Foundation; either version 2 of the
15 License, or (at your option) any later version.
16
17 This program is distributed in the hope that it will be useful, but
18 WITHOUT ANY WARRANTY; without even the implied warranty of
19 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
20 General Public License for more details.
21
22 You should have received a copy of the GNU General Public License
23 along with this program; if not, write to the Free Software
24 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
25 02111-1307, USA.
26
27 The GNU General Public License is contained in the file COPYING.
28*/
29
30/* Contributed by Julian Seward <jseward@acm.org> */
31
32
33#include "pub_core_basics.h"
34#include "pub_core_libcsetjmp.h" /* self */
35
36
37/* See include/pub_tool_libcsetjmp.h for background and rationale. */
38
sewardjda91ee72011-09-29 18:29:41 +000039/* The alternative implementations are for ppc{32,64}-linux and
40 {amd64,x86}-{linux,darwin}. See #259977. That leaves only
41 {arm,s390x}-linux using the gcc builtins now.
42*/
sewardj97d3ebb2011-04-11 18:36:34 +000043
sewardj2a88a012011-04-11 21:26:27 +000044/* ------------ ppc32-linux ------------ */
45
sewardj97d3ebb2011-04-11 18:36:34 +000046#if defined(VGP_ppc32_linux)
47
48__asm__(
49".text" "\n"
sewardj2a88a012011-04-11 21:26:27 +000050"" "\n"
sewardj97d3ebb2011-04-11 18:36:34 +000051".global VG_MINIMAL_SETJMP" "\n" // r3 = jmp_buf
52"VG_MINIMAL_SETJMP:" "\n"
53" stw 0, 0(3)" "\n"
54" stw 1, 4(3)" "\n"
55" stw 2, 8(3)" "\n"
56" stw 3, 12(3)" "\n"
57" stw 4, 16(3)" "\n"
58" stw 5, 20(3)" "\n"
59" stw 6, 24(3)" "\n"
60" stw 7, 28(3)" "\n"
61" stw 8, 32(3)" "\n"
62" stw 9, 36(3)" "\n"
63" stw 10, 40(3)" "\n"
64" stw 11, 44(3)" "\n"
65" stw 12, 48(3)" "\n"
66" stw 13, 52(3)" "\n"
67" stw 14, 56(3)" "\n"
68" stw 15, 60(3)" "\n"
69" stw 16, 64(3)" "\n"
70" stw 17, 68(3)" "\n"
71" stw 18, 72(3)" "\n"
72" stw 19, 76(3)" "\n"
73" stw 20, 80(3)" "\n"
74" stw 21, 84(3)" "\n"
75" stw 22, 88(3)" "\n"
76" stw 23, 92(3)" "\n"
77" stw 24, 96(3)" "\n"
78" stw 25, 100(3)" "\n"
79" stw 26, 104(3)" "\n"
80" stw 27, 108(3)" "\n"
81" stw 28, 112(3)" "\n"
82" stw 29, 116(3)" "\n"
83" stw 30, 120(3)" "\n"
84" stw 31, 124(3)" "\n"
85 // must use a caller-save register here as scratch, hence r4
86" mflr 4" "\n"
87" stw 4, 128(3)" "\n"
88" mfcr 4" "\n"
89" stw 4, 132(3)" "\n"
90" li 3, 0" "\n"
91" blr" "\n"
sewardj2a88a012011-04-11 21:26:27 +000092"" "\n"
sewardj97d3ebb2011-04-11 18:36:34 +000093
94
95".global VG_MINIMAL_LONGJMP" "\n"
96"VG_MINIMAL_LONGJMP:" "\n" // r3 = jmp_buf
97 // do r4 = 1
98 // and park it in the restore slot for r3 (the ret reg)
99" li 4, 1" "\n"
100" stw 4, 12(3)" "\n"
101 // restore everything except r3
102 // then r3 last of all
103 // then blr
104" lwz 0, 128(3)" "\n"
105" mtlr 0" "\n"
106" lwz 0, 132(3)" "\n"
107" mtcr 0" "\n"
108" lwz 0, 0(3)" "\n"
109" lwz 1, 4(3)" "\n"
110" lwz 2, 8(3)" "\n"
111 // r3 is done at the end
112" lwz 4, 16(3)" "\n"
113" lwz 5, 20(3)" "\n"
114" lwz 6, 24(3)" "\n"
115" lwz 7, 28(3)" "\n"
116" lwz 8, 32(3)" "\n"
117" lwz 9, 36(3)" "\n"
118" lwz 10, 40(3)" "\n"
119" lwz 11, 44(3)" "\n"
120" lwz 12, 48(3)" "\n"
121" lwz 13, 52(3)" "\n"
122" lwz 14, 56(3)" "\n"
123" lwz 15, 60(3)" "\n"
124" lwz 16, 64(3)" "\n"
125" lwz 17, 68(3)" "\n"
126" lwz 18, 72(3)" "\n"
127" lwz 19, 76(3)" "\n"
128" lwz 20, 80(3)" "\n"
129" lwz 21, 84(3)" "\n"
130" lwz 22, 88(3)" "\n"
131" lwz 23, 92(3)" "\n"
132" lwz 24, 96(3)" "\n"
133" lwz 25, 100(3)" "\n"
134" lwz 26, 104(3)" "\n"
135" lwz 27, 108(3)" "\n"
136" lwz 28, 112(3)" "\n"
137" lwz 29, 116(3)" "\n"
138" lwz 30, 120(3)" "\n"
139" lwz 31, 124(3)" "\n"
140" lwz 3, 12(3)" "\n"
141" blr" "\n"
sewardj2a88a012011-04-11 21:26:27 +0000142"" "\n"
sewardj97d3ebb2011-04-11 18:36:34 +0000143
144".previous" "\n"
145);
146
147#endif /* VGP_ppc32_linux */
sewardj6c591e12011-04-11 16:17:51 +0000148
149
sewardj2a88a012011-04-11 21:26:27 +0000150/* ------------ ppc64-linux ------------ */
151
carllcae0cc22014-08-07 23:17:29 +0000152#if defined(VGP_ppc64be_linux)
sewardj2a88a012011-04-11 21:26:27 +0000153
154__asm__(
155".section \".toc\",\"aw\"" "\n"
156
157".section \".text\"" "\n"
158".align 2" "\n"
159".p2align 4,,15" "\n"
160".globl VG_MINIMAL_SETJMP" "\n"
sewardj2a88a012011-04-11 21:26:27 +0000161".section \".opd\",\"aw\"" "\n"
162".align 3" "\n"
163"VG_MINIMAL_SETJMP:" "\n"
164".quad .L.VG_MINIMAL_SETJMP,.TOC.@tocbase,0" "\n"
165".previous" "\n"
166
167".type VG_MINIMAL_SETJMP, @function" "\n"
168".L.VG_MINIMAL_SETJMP:" "\n"
169" std 0, 0(3)" "\n"
170" std 1, 8(3)" "\n"
171" std 2, 16(3)" "\n"
172" std 3, 24(3)" "\n"
173" std 4, 32(3)" "\n"
174" std 5, 40(3)" "\n"
175" std 6, 48(3)" "\n"
176" std 7, 56(3)" "\n"
177" std 8, 64(3)" "\n"
178" std 9, 72(3)" "\n"
179" std 10, 80(3)" "\n"
180" std 11, 88(3)" "\n"
181" std 12, 96(3)" "\n"
182" std 13, 104(3)" "\n"
183" std 14, 112(3)" "\n"
184" std 15, 120(3)" "\n"
185" std 16, 128(3)" "\n"
186" std 17, 136(3)" "\n"
187" std 18, 144(3)" "\n"
188" std 19, 152(3)" "\n"
189" std 20, 160(3)" "\n"
190" std 21, 168(3)" "\n"
191" std 22, 176(3)" "\n"
192" std 23, 184(3)" "\n"
193" std 24, 192(3)" "\n"
194" std 25, 200(3)" "\n"
195" std 26, 208(3)" "\n"
196" std 27, 216(3)" "\n"
197" std 28, 224(3)" "\n"
198" std 29, 232(3)" "\n"
199" std 30, 240(3)" "\n"
200" std 31, 248(3)" "\n"
201 // must use a caller-save register here as scratch, hence r4
202" mflr 4" "\n"
203" std 4, 256(3)" "\n"
204" mfcr 4" "\n"
205" std 4, 264(3)" "\n"
206" li 3, 0" "\n"
207" blr" "\n"
208"" "\n"
209
210
211".globl VG_MINIMAL_LONGJMP" "\n"
212
213".section \".opd\",\"aw\"" "\n"
214".align 3" "\n"
215"VG_MINIMAL_LONGJMP:" "\n"
216".quad .L.VG_MINIMAL_LONGJMP,.TOC.@tocbase,0" "\n"
217".previous" "\n"
218
219".type VG_MINIMAL_LONGJMP, @function" "\n"
220".L.VG_MINIMAL_LONGJMP:" "\n"
221 // do r4 = 1
222 // and park it in the restore slot for r3 (the ret reg)
223" li 4, 1" "\n"
224" std 4, 24(3)" "\n"
225 // restore everything except r3
226 // then r3 last of all
227 // then blr
228" ld 0, 256(3)" "\n"
229" mtlr 0" "\n"
230" ld 0, 264(3)" "\n"
231" mtcr 0" "\n"
232" ld 0, 0(3)" "\n"
233" ld 1, 8(3)" "\n"
234" ld 2, 16(3)" "\n"
235 // r3 is done at the end
236" ld 4, 32(3)" "\n"
237" ld 5, 40(3)" "\n"
238" ld 6, 48(3)" "\n"
239" ld 7, 56(3)" "\n"
240" ld 8, 64(3)" "\n"
241" ld 9, 72(3)" "\n"
242" ld 10, 80(3)" "\n"
243" ld 11, 88(3)" "\n"
244" ld 12, 96(3)" "\n"
245" ld 13, 104(3)" "\n"
246" ld 14, 112(3)" "\n"
247" ld 15, 120(3)" "\n"
248" ld 16, 128(3)" "\n"
249" ld 17, 136(3)" "\n"
250" ld 18, 144(3)" "\n"
251" ld 19, 152(3)" "\n"
252" ld 20, 160(3)" "\n"
253" ld 21, 168(3)" "\n"
254" ld 22, 176(3)" "\n"
255" ld 23, 184(3)" "\n"
256" ld 24, 192(3)" "\n"
257" ld 25, 200(3)" "\n"
258" ld 26, 208(3)" "\n"
259" ld 27, 216(3)" "\n"
260" ld 28, 224(3)" "\n"
261" ld 29, 232(3)" "\n"
262" ld 30, 240(3)" "\n"
263" ld 31, 248(3)" "\n"
264" ld 3, 24(3)" "\n"
265" blr" "\n"
266"" "\n"
267
268".previous" "\n"
sewardj2a88a012011-04-11 21:26:27 +0000269);
270
carll582d5822014-08-07 23:35:54 +0000271#elif defined(VGP_ppc64le_linux)
272__asm__(
273".section \".toc\",\"aw\"" "\n"
274
275".section \".text\"" "\n"
276".align 2" "\n"
277".p2align 4,,15" "\n"
278".globl VG_MINIMAL_SETJMP" "\n"
279".type VG_MINIMAL_SETJMP,@function" "\n"
280"VG_MINIMAL_SETJMP:" "\n"
281" .localentry VG_MINIMAL_SETJMP, .-VG_MINIMAL_SETJMP" "\n"
282" std 0, 0(3)" "\n"
283" std 1, 8(3)" "\n"
284" std 2, 16(3)" "\n"
285" std 3, 24(3)" "\n"
286" std 4, 32(3)" "\n"
287" std 5, 40(3)" "\n"
288" std 6, 48(3)" "\n"
289" std 7, 56(3)" "\n"
290" std 8, 64(3)" "\n"
291" std 9, 72(3)" "\n"
292" std 10, 80(3)" "\n"
293" std 11, 88(3)" "\n"
294" std 12, 96(3)" "\n"
295" std 13, 104(3)" "\n"
296" std 14, 112(3)" "\n"
297" std 15, 120(3)" "\n"
298" std 16, 128(3)" "\n"
299" std 17, 136(3)" "\n"
300" std 18, 144(3)" "\n"
301" std 19, 152(3)" "\n"
302" std 20, 160(3)" "\n"
303" std 21, 168(3)" "\n"
304" std 22, 176(3)" "\n"
305" std 23, 184(3)" "\n"
306" std 24, 192(3)" "\n"
307" std 25, 200(3)" "\n"
308" std 26, 208(3)" "\n"
309" std 27, 216(3)" "\n"
310" std 28, 224(3)" "\n"
311" std 29, 232(3)" "\n"
312" std 30, 240(3)" "\n"
313" std 31, 248(3)" "\n"
314// must use a caller-save register here as scratch, hence r4
315" mflr 4" "\n"
316" std 4, 256(3)" "\n"
317" mfcr 4" "\n"
318" std 4, 264(3)" "\n"
319" li 3, 0" "\n"
320" blr" "\n"
321"" "\n"
322
323
324".globl VG_MINIMAL_LONGJMP" "\n"
325".type VG_MINIMAL_LONGJMP, @function" "\n"
326"VG_MINIMAL_LONGJMP:" "\n"
327" .localentry VG_MINIMAL_LONGJMP, .-VG_MINIMAL_LONGJMP" "\n"
328 // do r4 = 1
329 // and park it in the restore slot for r3 (the ret reg)
330" li 4, 1" "\n"
331" std 4, 24(3)" "\n"
332 // restore everything except r3
333 // then r3 last of all
334 // then blr
335" ld 0, 256(3)" "\n"
336" mtlr 0" "\n"
337" ld 0, 264(3)" "\n"
338" mtcr 0" "\n"
339" ld 0, 0(3)" "\n"
340" ld 1, 8(3)" "\n"
341" ld 2, 16(3)" "\n"
342 // r3 is done at the end
343" ld 4, 32(3)" "\n"
344" ld 5, 40(3)" "\n"
345" ld 6, 48(3)" "\n"
346" ld 7, 56(3)" "\n"
347" ld 8, 64(3)" "\n"
348" ld 9, 72(3)" "\n"
349" ld 10, 80(3)" "\n"
350" ld 11, 88(3)" "\n"
351" ld 12, 96(3)" "\n"
352" ld 13, 104(3)" "\n"
353" ld 14, 112(3)" "\n"
354" ld 15, 120(3)" "\n"
355" ld 16, 128(3)" "\n"
356" ld 17, 136(3)" "\n"
357" ld 18, 144(3)" "\n"
358" ld 19, 152(3)" "\n"
359" ld 20, 160(3)" "\n"
360" ld 21, 168(3)" "\n"
361" ld 22, 176(3)" "\n"
362" ld 23, 184(3)" "\n"
363" ld 24, 192(3)" "\n"
364" ld 25, 200(3)" "\n"
365" ld 26, 208(3)" "\n"
366" ld 27, 216(3)" "\n"
367" ld 28, 224(3)" "\n"
368" ld 29, 232(3)" "\n"
369" ld 30, 240(3)" "\n"
370" ld 31, 248(3)" "\n"
371" ld 3, 24(3)" "\n"
372" blr" "\n"
373"" "\n"
374
375".previous" "\n"
376);
carllcae0cc22014-08-07 23:17:29 +0000377#endif /* VGP_ppc64be_linux */
sewardj2a88a012011-04-11 21:26:27 +0000378
sewardjfc824cb2011-09-29 17:33:58 +0000379
sewardjda91ee72011-09-29 18:29:41 +0000380/* ------------ amd64-{linux,darwin} ------------ */
sewardjfc824cb2011-09-29 17:33:58 +0000381
sewardjda91ee72011-09-29 18:29:41 +0000382#if defined(VGP_amd64_linux) || defined(VGP_amd64_darwin)
sewardjfc824cb2011-09-29 17:33:58 +0000383
384__asm__(
385".text" "\n"
386"" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000387
388#if defined(VGP_amd64_linux)
sewardjfc824cb2011-09-29 17:33:58 +0000389".global VG_MINIMAL_SETJMP" "\n" // rdi = jmp_buf
390"VG_MINIMAL_SETJMP:" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000391
392#elif defined(VGP_amd64_darwin)
393".globl _VG_MINIMAL_SETJMP" "\n" // rdi = jmp_buf
394"_VG_MINIMAL_SETJMP:" "\n"
395
396#else
397# error "Huh?"
398#endif
399
sewardjfc824cb2011-09-29 17:33:58 +0000400" movq %rax, 0(%rdi)" "\n"
401" movq %rbx, 8(%rdi)" "\n"
402" movq %rcx, 16(%rdi)" "\n"
403" movq %rdx, 24(%rdi)" "\n"
404" movq %rdi, 32(%rdi)" "\n"
405" movq %rsi, 40(%rdi)" "\n"
406" movq %rbp, 48(%rdi)" "\n"
407" movq %rsp, 56(%rdi)" "\n"
408" movq %r8, 64(%rdi)" "\n"
409" movq %r9, 72(%rdi)" "\n"
410" movq %r10, 80(%rdi)" "\n"
411" movq %r11, 88(%rdi)" "\n"
412" movq %r12, 96(%rdi)" "\n"
413" movq %r13, 104(%rdi)" "\n"
414" movq %r14, 112(%rdi)" "\n"
415" movq %r15, 120(%rdi)" "\n"
416 // store the return address
417" movq 0(%rsp), %rax" "\n"
418" movq %rax, 128(%rdi)" "\n"
419 // and return zero
420" movq $0, %rax" "\n"
421" ret" "\n"
422"" "\n"
423
sewardjda91ee72011-09-29 18:29:41 +0000424
425#if defined(VGP_amd64_linux)
426".global VG_MINIMAL_LONGJMP" "\n"
sewardjfc824cb2011-09-29 17:33:58 +0000427"VG_MINIMAL_LONGJMP:" "\n" // rdi = jmp_buf
sewardjda91ee72011-09-29 18:29:41 +0000428
429#elif defined(VGP_amd64_darwin)
430".globl _VG_MINIMAL_LONGJMP" "\n"
431"_VG_MINIMAL_LONGJMP:" "\n" // rdi = jmp_buf
432
433#else
434# error "Huh?"
435#endif
sewardjfc824cb2011-09-29 17:33:58 +0000436 // skip restoring rax; it's pointless
437" movq 8(%rdi), %rbx" "\n"
438" movq 16(%rdi), %rcx" "\n"
439" movq 24(%rdi), %rdx" "\n"
440 // defer restoring rdi; we still need it
441" movq 40(%rdi), %rsi" "\n"
442" movq 48(%rdi), %rbp" "\n"
443" movq 56(%rdi), %rsp" "\n"
444" movq 64(%rdi), %r8" "\n"
445" movq 72(%rdi), %r9" "\n"
446" movq 80(%rdi), %r10" "\n"
447" movq 88(%rdi), %r11" "\n"
448" movq 96(%rdi), %r12" "\n"
449" movq 104(%rdi), %r13" "\n"
450" movq 112(%rdi), %r14" "\n"
451" movq 120(%rdi), %r15" "\n"
452 // restore the return address
453" movq 128(%rdi), %rax" "\n"
454 // restore rdi; this is the last use
455" movq 32(%rdi), %rdi" "\n"
456 // make %rsp look like we really did a return
457" addq $8, %rsp" "\n"
458 // continue at RA of original call. Note: this is a
459 // nasty trick. We assume that %rax is nonzero, and so the
460 // caller can differentiate this case from the normal _SETJMP
461 // return case. If the return address ever is zero, then
462 // we're hosed; but that seems pretty unlikely given that it
463 // would mean we'd be executing at the wraparound point of the
464 // address space.
465" jmp *%rax" "\n"
466"" "\n"
467
sewardjda91ee72011-09-29 18:29:41 +0000468#if !defined(VGP_amd64_darwin)
sewardjfc824cb2011-09-29 17:33:58 +0000469".previous" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000470#endif
sewardjfc824cb2011-09-29 17:33:58 +0000471);
472
sewardjda91ee72011-09-29 18:29:41 +0000473#endif /* VGP_amd64_linux || VGP_amd64_darwin */
sewardjfc824cb2011-09-29 17:33:58 +0000474
475
sewardjda91ee72011-09-29 18:29:41 +0000476/* ------------ x86-{linux,darwin} ------------ */
sewardjfc824cb2011-09-29 17:33:58 +0000477
sewardjda91ee72011-09-29 18:29:41 +0000478#if defined(VGP_x86_linux) || defined(VGP_x86_darwin)
sewardjfc824cb2011-09-29 17:33:58 +0000479
480__asm__(
481".text" "\n"
482"" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000483
484#if defined(VGP_x86_linux)
sewardjfc824cb2011-09-29 17:33:58 +0000485".global VG_MINIMAL_SETJMP" "\n" // eax = jmp_buf
486"VG_MINIMAL_SETJMP:" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000487
488#elif defined(VGP_x86_darwin)
489".globl _VG_MINIMAL_SETJMP" "\n" // eax = jmp_buf
490"_VG_MINIMAL_SETJMP:" "\n"
491
492#else
493# error "Huh?"
494#endif
495
sewardjfc824cb2011-09-29 17:33:58 +0000496" movl %eax, 0(%eax)" "\n"
497" movl %ebx, 4(%eax)" "\n"
498" movl %ecx, 8(%eax)" "\n"
499" movl %edx, 12(%eax)" "\n"
500" movl %edi, 16(%eax)" "\n"
501" movl %esi, 20(%eax)" "\n"
502" movl %ebp, 24(%eax)" "\n"
503" movl %esp, 28(%eax)" "\n"
504 // store the return address
505" movl 0(%esp), %ebx" "\n"
506" movl %ebx, 32(%eax)" "\n"
507 // un-trash ebx (necessary? i don't know)
508" movl 4(%eax), %ebx" "\n"
509 // and return zero
510" movl $0, %eax" "\n"
511" ret" "\n"
512"" "\n"
513
sewardjda91ee72011-09-29 18:29:41 +0000514
515#if defined(VGP_x86_linux)
516".global VG_MINIMAL_LONGJMP" "\n"
sewardjfc824cb2011-09-29 17:33:58 +0000517"VG_MINIMAL_LONGJMP:" "\n" // eax = jmp_buf
sewardjda91ee72011-09-29 18:29:41 +0000518
519#elif defined(VGP_x86_darwin)
520".globl _VG_MINIMAL_LONGJMP" "\n"
521"_VG_MINIMAL_LONGJMP:" "\n" // eax = jmp_buf
522
523#else
524# error "Huh?"
525#endif
526
sewardjfc824cb2011-09-29 17:33:58 +0000527 // skip restoring eax; it's pointless
528" movl 4(%eax), %ebx" "\n"
529" movl 8(%eax), %ecx" "\n"
530" movl 12(%eax), %edx" "\n"
531" movl 16(%eax), %edi" "\n"
532" movl 20(%eax), %esi" "\n"
533" movl 24(%eax), %ebp" "\n"
534" movl 28(%eax), %esp" "\n"
535 // restore the return address
536" movl 32(%eax), %eax" "\n"
537 // make %esp look like we really did a return
538" addl $4, %esp" "\n"
539 // continue at RA of original call. Same zero-vs-nonzero
540 // trick/assumption as documented for the amd64-linux case.
541" jmp *%eax" "\n"
542"" "\n"
543
sewardjda91ee72011-09-29 18:29:41 +0000544#if !defined(VGP_x86_darwin)
sewardjfc824cb2011-09-29 17:33:58 +0000545".previous" "\n"
sewardjda91ee72011-09-29 18:29:41 +0000546#endif
sewardjfc824cb2011-09-29 17:33:58 +0000547);
548
sewardjda91ee72011-09-29 18:29:41 +0000549#endif /* VGP_x86_linux || VGP_x86_darwin */
sewardjfc824cb2011-09-29 17:33:58 +0000550
dejanj5f790e82013-07-25 08:22:08 +0000551#if defined(VGP_mips32_linux)
552
553__asm__(
554".text \n\t"
555".globl VG_MINIMAL_SETJMP; \n\t"
556".align 2; \n\t"
557"VG_MINIMAL_SETJMP: \n\t" /* a0 = jmp_buf */
558" sw $s0, 0($a0) \n\t" /* Save registers s0-s7. */
559" sw $s1, 4($a0) \n\t"
560" sw $s2, 8($a0) \n\t"
561" sw $s3, 12($a0) \n\t"
562" sw $s4, 16($a0) \n\t"
563" sw $s5, 20($a0) \n\t"
564" sw $s6, 24($a0) \n\t"
565" sw $s7, 28($a0) \n\t"
566" sw $s8, 32($a0) \n\t" /* Frame pointer. */
567" sw $ra, 36($a0) \n\t" /* Return address. */
568" sw $gp, 40($a0) \n\t" /* Global data pointer. */
569" sw $sp, 44($a0) \n\t" /* Stack pointer. */
570
571" move $v0, $zero \n\t" /* Return zero. */
572" j $ra \n\t"
573" nop \n\t"
dejanj751c1e62013-08-15 13:37:29 +0000574".previous \n\t"
dejanj5f790e82013-07-25 08:22:08 +0000575" \n\t"
576".globl VG_MINIMAL_LONGJMP; \n\t"
577".align 2; \n\t"
578"VG_MINIMAL_LONGJMP: \n\t" /* a0 = jmp_buf */
579" lw $s0, 0($a0) \n\t" /* Restore registers s0-s7. */
580" lw $s1, 4($a0) \n\t"
581" lw $s2, 8($a0) \n\t"
582" lw $s3, 12($a0) \n\t"
583" lw $s4, 16($a0) \n\t"
584" lw $s5, 20($a0) \n\t"
585" lw $s6, 24($a0) \n\t"
586" lw $s7, 28($a0) \n\t"
587" lw $s8, 32($a0) \n\t" /* Frame pointer. */
588" lw $ra, 36($a0) \n\t" /* Return address. */
589" lw $gp, 40($a0) \n\t" /* Global data pointer. */
590" lw $sp, 44($a0) \n\t" /* Stack pointer. */
591
592/* Checking whether second argument is zero. */
593" bnez $a1, 1f \n\t"
594" nop \n\t"
595" addi $a1, $a1, 1 \n\t" /* We must return 1 if val=0. */
596"1: \n\t"
597" move $v0, $a1 \n\t" /* Return value of second argument. */
598" j $ra \n\t"
dejanj751c1e62013-08-15 13:37:29 +0000599" nop \n\t"
600".previous \n\t"
dejanj5f790e82013-07-25 08:22:08 +0000601);
602#endif /* VGP_mips32_linux */
603
sewardj6c591e12011-04-11 16:17:51 +0000604/*--------------------------------------------------------------------*/
605/*--- end ---*/
606/*--------------------------------------------------------------------*/