_setjmp.S revision 271337
197403Sobrien/* $NetBSD: _setjmp.S,v 1.12 2013/04/19 13:45:45 matt Exp $ */ 297403Sobrien 3169691Skan/* 497403Sobrien * Copyright (c) 1997 Mark Brinicombe 597403Sobrien * All rights reserved. 697403Sobrien * 797403Sobrien * Redistribution and use in source and binary forms, with or without 897403Sobrien * modification, are permitted provided that the following conditions 997403Sobrien * are met: 1097403Sobrien * 1. Redistributions of source code must retain the above copyright 1197403Sobrien * notice, this list of conditions and the following disclaimer. 1297403Sobrien * 2. Redistributions in binary form must reproduce the above copyright 1397403Sobrien * notice, this list of conditions and the following disclaimer in the 1497403Sobrien * documentation and/or other materials provided with the distribution. 1597403Sobrien * 3. All advertising materials mentioning features or use of this software 1697403Sobrien * must display the following acknowledgement: 1797403Sobrien * This product includes software developed by Mark Brinicombe 18169691Skan * 4. Neither the name of the University nor the names of its contributors 1997403Sobrien * may be used to endorse or promote products derived from this software 2097403Sobrien * without specific prior written permission. 2197403Sobrien * 2297403Sobrien * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 2397403Sobrien * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 2497403Sobrien * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 2597403Sobrien * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 2697403Sobrien * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 2797403Sobrien * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 2897403Sobrien * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 2997403Sobrien * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 3097403Sobrien * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 3197403Sobrien * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 3297403Sobrien * SUCH DAMAGE. 3397403Sobrien */ 3497403Sobrien 3597403Sobrien#if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS) 3697403Sobrien#error FPA is not supported anymore 3797403Sobrien#endif 3897403Sobrien 3997403Sobrien#if defined(__ARM_EABI__) && !defined(_STANDALONE) 4097403Sobrien .fpu vfp 4197403Sobrien#endif 4297403Sobrien 4397403Sobrien#include <machine/asm.h> 4497403Sobrien#include <machine/setjmp.h> 4597403Sobrien 4697403Sobrien__FBSDID("$FreeBSD: stable/10/lib/libc/arm/gen/_setjmp.S 271337 2014-09-09 22:24:01Z ian $"); 4797403Sobrien 4897403Sobrien/* 4997403Sobrien * C library -- _setjmp, _longjmp 5097403Sobrien * 5197403Sobrien * _longjmp(a,v) 5297403Sobrien * will generate a "return(v)" from the last call to 5397403Sobrien * _setjmp(a) 5497403Sobrien * by restoring registers from the stack. 5597403Sobrien * The previous signal state is NOT restored. 5697403Sobrien * 5797403Sobrien * Note: r0 is the return value 5897403Sobrien * r1-r3,ip are scratch registers in functions 5997403Sobrien */ 6097403Sobrien 61132720SkanENTRY(_setjmp) 62132720Skan ldr r1, .L_setjmp_magic 6397403Sobrien 64169691Skan#if defined(__ARM_EABI__) && !defined(_STANDALONE) 65169691Skan ldr r2, .Lfpu_present 6697403Sobrien#ifdef PIC 6797403Sobrien GOT_INIT(r3, .L_setjmp_got, .L_setjmp_gotinit) 6897403Sobrien ldr r2, [r2, r3] 6997403Sobrien#else 7097403Sobrien ldr r2, [r2] 71132720Skan#endif 7297403Sobrien teq r2, #0 /* do we have a FPU? */ 7397403Sobrien beq 1f /* no, don't save VFP registers */ 7497403Sobrien 7597403Sobrien orr r1, r1, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP) 7697403Sobrien /* change magic to VFP magic */ 7797403Sobrien add r2, r0, #(_JB_REG_D8 * 4) 78132720Skan vstmia r2, {d8-d15} 79132720Skan vmrs r2, fpscr 80132720Skan str r2, [r0, #(_JB_REG_FPSCR * 4)] 8197403Sobrien1: 82132720Skan#endif /* __ARM_EABI__ */ 8397403Sobrien 8497403Sobrien str r1, [r0] 85132720Skan 86132720Skan add r0, r0, #(_JB_REG_R4 * 4) 8797403Sobrien /* Store integer registers */ 88132720Skan stmia r0, {r4-r14} 8997403Sobrien 90132720Skan mov r0, #0x00000000 9197403Sobrien RET 92132720SkanEND(_setjmp) 93132720Skan 9497403Sobrien.L_setjmp_magic: 9597403Sobrien .word _JB_MAGIC__SETJMP 9697403Sobrien#if defined(__ARM_EABI__) && !defined(_STANDALONE) 9797403Sobrien GOT_INITSYM(.L_setjmp_got, .L_setjmp_gotinit) 9897403Sobrien.Lfpu_present: 99132720Skan .word PIC_SYM(_libc_arm_fpu_present, GOTOFF) 100132720Skan#endif /* __ARM_EABI__ */ 10197403Sobrien 10297403SobrienWEAK_ALIAS(___longjmp, _longjmp) 10397403SobrienENTRY(_longjmp) 10497403Sobrien ldr r2, [r0] /* get magic from jmp_buf */ 10597403Sobrien bic r3, r2, #(_JB_MAGIC__SETJMP ^ _JB_MAGIC__SETJMP_VFP) 10697403Sobrien /* ignore VFP-ness of magic */ 10797403Sobrien ldr ip, .L_setjmp_magic /* load magic */ 108169691Skan teq ip, r3 /* magic correct? */ 109169691Skan bne botch /* no, botch */ 11097403Sobrien 111#if defined(__ARM_EABI__) && !defined(_STANDALONE) 112 teq r3, r2 /* did magic change? */ 113 beq 1f /* no, don't restore VFP */ 114 add ip, r0, #(_JB_REG_D8 * 4) 115 vldmia ip, {d8-d15} 116 ldr ip, [r0, #(_JB_REG_FPSCR * 4)] 117 vmsr fpscr, ip 1181: 119#endif /* __ARM_EABI__ */ 120 121 add r0, r0, #(_JB_REG_R4 * 4) 122 /* Restore integer registers */ 123 ldmia r0, {r4-r14} 124 125 /* Validate sp and r14 */ 126 teq sp, #0 127 teqne r14, #0 128 beq botch 129 130 /* Set return value */ 131 movs r0, r1 132 moveq r0, #0x00000001 133 RET 134 135 /* validation failed, die die die. */ 136botch: 137#if !defined(_STANDALONE) 138 bl PIC_SYM(_C_LABEL(longjmperror), PLT) 139 bl PIC_SYM(_C_LABEL(abort), PLT) 140 b . - 8 /* Cannot get here */ 141#else 142 b . 143#endif 144END(_longjmp) 145