11dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* $OpenBSD: _setjmp.S,v 1.2 2004/02/01 05:40:52 drahn Exp $ */ 21dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* $NetBSD: _setjmp.S,v 1.5 2003/04/05 23:08:51 bjh21 Exp $ */ 31dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 41dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 51dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Copyright (c) 1997 Mark Brinicombe 668b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner * Copyright (c) 2010 Android Open Source Project. 71dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * All rights reserved. 81dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 91dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Redistribution and use in source and binary forms, with or without 101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * modification, are permitted provided that the following conditions 111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * are met: 121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 1. Redistributions of source code must retain the above copyright 131dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer. 141dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 2. Redistributions in binary form must reproduce the above copyright 151dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * notice, this list of conditions and the following disclaimer in the 161dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * documentation and/or other materials provided with the distribution. 171dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 3. All advertising materials mentioning features or use of this software 181dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * must display the following acknowledgement: 191dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * This product includes software developed by Mark Brinicombe 201dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 4. Neither the name of the University nor the names of its contributors 211dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * may be used to endorse or promote products derived from this software 221dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * without specific prior written permission. 231dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 241dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 251dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 261dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 271dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 281dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 291dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 301dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 311dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 321dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 331dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 341dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * SUCH DAMAGE. 351dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 361dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 371dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <machine/asm.h> 381dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project#include <machine/setjmp.h> 3968b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner#include <machine/cpu-features.h> 401dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 411dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project/* 421dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * C library -- _setjmp, _longjmp 431dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 441dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * _longjmp(a,v) 451dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * will generate a "return(v)" from the last call to 461dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * _setjmp(a) 471dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * by restoring registers from the stack. 481dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * The previous signal state is NOT restored. 491dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * 501dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * Note: r0 is the return value 511dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project * r1-r3 are scratch registers in functions 521dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project */ 531dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 541dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectENTRY(_setjmp) 551dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr r1, .L_setjmp_magic 5668b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner str r1, [r0, #(_JB_MAGIC * 4)] 5768b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner 5868b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner /* Store core registers */ 5968b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner add r1, r0, #(_JB_CORE_BASE * 4) 6068b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner stmia r1, {r4-r14} 6168b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner 6268b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner#ifdef __ARM_HAVE_VFP 6368b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner /* Store floating-point registers */ 6468b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner add r1, r0, #(_JB_FLOAT_BASE * 4) 6568b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner vstmia r1, {d8-d15} 6668b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner /* Store floating-point state */ 6768b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner fmrx r1, fpscr 6868b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner str r1, [r0, #(_JB_FLOAT_STATE * 4)] 6968b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner#endif /* __ARM_HAVE_VFP */ 701dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 711dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mov r0, #0x00000000 721dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bx lr 73420878c6908cf9c2862888477ec3f424a06cf172Kenny RootEND(_setjmp) 741dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 751dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project.L_setjmp_magic: 761dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project .word _JB_MAGIC__SETJMP 771dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 781dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source ProjectENTRY(_longjmp) 791dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project ldr r2, .L_setjmp_magic 8068b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner ldr r3, [r0, #(_JB_MAGIC * 4)] 811dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project teq r2, r3 821dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bne botch 831dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 8468b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner#ifdef __ARM_HAVE_VFP 8568b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner /* Restore floating-point registers */ 8668b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner add r2, r0, #(_JB_FLOAT_BASE * 4) 8768b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner vldmia r2, {d8-d15} 8868b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner /* Restore floating-point state */ 8968b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner ldr r2, [r0, #(_JB_FLOAT_STATE * 4)] 9068b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner fmxr fpscr, r2 9168b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner#endif /* __ARM_HAVE_VFP */ 9268b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner 9368b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner /* Restore core registers */ 9468b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner add r2, r0, #(_JB_CORE_BASE * 4) 9568b5f556710909d292b5b285ee2c5e4d30e6476eDavid 'Digit' Turner ldmia r2, {r4-r14} 961dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 971dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Validate sp and r14 */ 981dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project teq sp, #0 991dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project teqne r14, #0 1001dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project beq botch 1011dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1021dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* Set return value */ 1031dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project mov r0, r1 1041dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project teq r0, #0x00000000 1051dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project moveq r0, #0x00000001 1061dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bx lr 1071dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project 1081dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project /* validation failed, die die die. */ 1091dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Projectbotch: 1101dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bl PIC_SYM(_C_LABEL(longjmperror), PLT) 1111dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project bl PIC_SYM(_C_LABEL(abort), PLT) 1121dc9e472e19acfe6dc7f41e429236e7eef7ceda1The Android Open Source Project b . - 8 /* Cannot get here */ 113420878c6908cf9c2862888477ec3f424a06cf172Kenny RootEND(_longjmp) 114