/* $NetBSD: _setjmp.S,v 1.12 2013/04/19 13:45:45 matt Exp $ */12/*3* Copyright (c) 1997 Mark Brinicombe4* All rights reserved.5*6* Redistribution and use in source and binary forms, with or without7* modification, are permitted provided that the following conditions8* are met:9* 1. Redistributions of source code must retain the above copyright10* notice, this list of conditions and the following disclaimer.11* 2. Redistributions in binary form must reproduce the above copyright12* notice, this list of conditions and the following disclaimer in the13* documentation and/or other materials provided with the distribution.14* 3. All advertising materials mentioning features or use of this software15* must display the following acknowledgement:16* This product includes software developed by Mark Brinicombe17* 4. Neither the name of the University nor the names of its contributors18* may be used to endorse or promote products derived from this software19* without specific prior written permission.20*21* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND22* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE23* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE24* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE25* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL26* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS27* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)28* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT29* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY30* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF31* SUCH DAMAGE.32*/3334#if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS)35#error FPA is not supported anymore36#endif3738#if !defined(_STANDALONE)39.fpu vfp40#endif4142#include <machine/asm.h>43#include <machine/setjmp.h>44/*45* C library -- _setjmp, _longjmp46*47* _longjmp(a,v)48* will generate a "return(v)" from the last call to49* _setjmp(a)50* by restoring registers from the stack.51* The previous signal state is NOT restored.52*53* Note: r0 is the return value54* r1-r3,ip are scratch registers in functions55*/5657ENTRY(_setjmp)58ldr r1, .L_setjmp_magic5960#if !defined(_STANDALONE) && !defined(SOFTFLOAT_FOR_GCC)61add r2, r0, #(_JB_REG_D8 * 4)62vstmia r2, {d8-d15}63vmrs r2, fpscr64str r2, [r0, #(_JB_REG_FPSCR * 4)]65#endif /* !_STANDALONE && !SOFTFLOAT_FOR_GCC */6667str r1, [r0]6869add r0, r0, #(_JB_REG_R4 * 4)70/* Store integer registers */71#ifndef __thumb__72stmia r0, {r4-r14}73#else74stmia r0, {r4-r12}75str r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)]76str r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)]77#endif7879mov r0, #0x0000000080RET81END(_setjmp)8283.L_setjmp_magic:84.word _JB_MAGIC__SETJMP8586WEAK_ALIAS(___longjmp, _longjmp)87ENTRY(_longjmp)88ldr r2, [r0] /* get magic from jmp_buf */89ldr ip, .L_setjmp_magic /* load magic */90teq ip, r2 /* magic correct? */91bne botch /* no, botch */9293#if !defined(_STANDALONE) && !defined(SOFTFLOAT_FOR_GCC)94add ip, r0, #(_JB_REG_D8 * 4)95vldmia ip, {d8-d15}96ldr ip, [r0, #(_JB_REG_FPSCR * 4)]97vmsr fpscr, ip98#endif /* !_STANDALONE && !SOFTFLOAT_FOR_GCC */99100add r0, r0, #(_JB_REG_R4 * 4)101/* Restore integer registers */102#ifndef __thumb__103ldmia r0, {r4-r14}104#else105ldmia r0, {r4-r12}106ldr r13, [r0, #((_JB_REG_R13 - _JB_REG_R4) * 4)]107ldr r14, [r0, #((_JB_REG_R14 - _JB_REG_R4) * 4)]108#endif109110/* Validate sp and r14 */111teq sp, #0112it ne113teqne r14, #0114it eq115beq botch116117/* Set return value */118movs r0, r1119it eq120moveq r0, #0x00000001121RET122123/* validation failed, die die die. */124botch:125#if !defined(_STANDALONE)126bl PIC_SYM(_C_LABEL(longjmperror), PLT)127bl PIC_SYM(_C_LABEL(abort), PLT)1281: b 1b /* Cannot get here */129#else130b .131#endif132END(_longjmp)133134.section .note.GNU-stack,"",%progbits135136137