xref: /freebsd/lib/libc/arm/gen/setjmp.S (revision f2e71517e0b886518f755b55931807a67478a564)
18ed717deSAndrew Turner/*	$NetBSD: setjmp.S,v 1.14 2013/04/19 13:45:45 matt Exp $	*/
22357939bSOlivier Houchard
32357939bSOlivier Houchard/*
42357939bSOlivier Houchard * Copyright (c) 1997 Mark Brinicombe
52357939bSOlivier Houchard * All rights reserved.
62357939bSOlivier Houchard *
72357939bSOlivier Houchard * Redistribution and use in source and binary forms, with or without
82357939bSOlivier Houchard * modification, are permitted provided that the following conditions
92357939bSOlivier Houchard * are met:
102357939bSOlivier Houchard * 1. Redistributions of source code must retain the above copyright
112357939bSOlivier Houchard *    notice, this list of conditions and the following disclaimer.
122357939bSOlivier Houchard * 2. Redistributions in binary form must reproduce the above copyright
132357939bSOlivier Houchard *    notice, this list of conditions and the following disclaimer in the
142357939bSOlivier Houchard *    documentation and/or other materials provided with the distribution.
152357939bSOlivier Houchard * 3. All advertising materials mentioning features or use of this software
162357939bSOlivier Houchard *    must display the following acknowledgement:
172357939bSOlivier Houchard *	This product includes software developed by Mark Brinicombe
182357939bSOlivier Houchard * 4. Neither the name of the University nor the names of its contributors
192357939bSOlivier Houchard *    may be used to endorse or promote products derived from this software
202357939bSOlivier Houchard *    without specific prior written permission.
212357939bSOlivier Houchard *
222357939bSOlivier Houchard * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
232357939bSOlivier Houchard * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
242357939bSOlivier Houchard * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
252357939bSOlivier Houchard * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
262357939bSOlivier Houchard * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
272357939bSOlivier Houchard * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
282357939bSOlivier Houchard * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
292357939bSOlivier Houchard * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
302357939bSOlivier Houchard * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
312357939bSOlivier Houchard * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
322357939bSOlivier Houchard * SUCH DAMAGE.
332357939bSOlivier Houchard */
342357939bSOlivier Houchard
358ed717deSAndrew Turner#if !defined(__SOFTFP__) && !defined(__VFP_FP__) && !defined(__ARM_PCS)
368ed717deSAndrew Turner#error FPA is not supported anymore
378ed717deSAndrew Turner#endif
388ed717deSAndrew Turner
398e03dd59SAndrew Turner#ifdef __ARM_EABI__
408e03dd59SAndrew Turner	.fpu	vfp
418e03dd59SAndrew Turner#endif
428e03dd59SAndrew Turner
432357939bSOlivier Houchard#include <machine/asm.h>
448ed717deSAndrew Turner#include <machine/setjmp.h>
458ed717deSAndrew Turner
462357939bSOlivier Houchard__FBSDID("$FreeBSD$");
478ed717deSAndrew Turner
482357939bSOlivier Houchard/*
492357939bSOlivier Houchard * C library -- setjmp, longjmp
502357939bSOlivier Houchard *
512357939bSOlivier Houchard *	longjmp(a,v)
522357939bSOlivier Houchard * will generate a "return(v)" from the last call to
532357939bSOlivier Houchard *	setjmp(a)
542357939bSOlivier Houchard * by restoring registers from the stack.
552357939bSOlivier Houchard * The previous signal state is restored.
562357939bSOlivier Houchard */
572357939bSOlivier Houchard
582357939bSOlivier HouchardENTRY(setjmp)
592357939bSOlivier Houchard	/* Block all signals and retrieve the old signal mask */
602357939bSOlivier Houchard	stmfd	sp!, {r0, r14}
618ed717deSAndrew Turner	add	r2, r0, #(_JB_SIGMASK * 4)	/* oset */
628ed717deSAndrew Turner	mov	r1, #0x00000000			/* set */
633d90a3cdSOlivier Houchard	mov	r0, #0x00000001			/* SIG_BLOCK */
643d90a3cdSOlivier Houchard	bl	PIC_SYM(_C_LABEL(sigprocmask), PLT)
652357939bSOlivier Houchard	ldmfd	sp!, {r0, r14}
662357939bSOlivier Houchard
672357939bSOlivier Houchard	ldr	r1, .Lsetjmp_magic
688e03dd59SAndrew Turner
698e03dd59SAndrew Turner#ifdef __ARM_EABI__
708e03dd59SAndrew Turner	ldr	r2, .Lfpu_present
718e03dd59SAndrew Turner#ifdef PIC
728e03dd59SAndrew Turner	GOT_INIT(r3, .Lsetjmp_got, .Lsetjmp_gotinit)
738e03dd59SAndrew Turner	ldr	r2, [r2, r3]
748e03dd59SAndrew Turner#else
758e03dd59SAndrew Turner	ldr	r2, [r2]
768e03dd59SAndrew Turner#endif
778e03dd59SAndrew Turner	teq	r2, #0		/* do we have a FPU? */
788e03dd59SAndrew Turner	beq	1f		/*   no, don't save VFP registers */
798e03dd59SAndrew Turner
808e03dd59SAndrew Turner	orr	r1, r1, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
818e03dd59SAndrew Turner				/* change magic to VFP magic */
828e03dd59SAndrew Turner	add	r2, r0, #(_JB_REG_D8 * 4)
838e03dd59SAndrew Turner	vstmia	r2, {d8-d15}
848e03dd59SAndrew Turner	vmrs	r2, fpscr
858e03dd59SAndrew Turner	str	r2, [r0, #(_JB_REG_FPSCR * 4)]
868e03dd59SAndrew Turner1:
878e03dd59SAndrew Turner#endif /* __ARM_EABI__ */
888e03dd59SAndrew Turner
898ed717deSAndrew Turner	str	r1, [r0]		/* store magic */
902357939bSOlivier Houchard
912357939bSOlivier Houchard	/* Store integer registers */
928ed717deSAndrew Turner	add	r0, r0, #(_JB_REG_R4 * 4)
932357939bSOlivier Houchard        stmia	r0, {r4-r14}
942357939bSOlivier Houchard        mov	r0, #0x00000000
9531489a9aSOlivier Houchard	RET
962357939bSOlivier Houchard
972357939bSOlivier Houchard.Lsetjmp_magic:
982357939bSOlivier Houchard	.word	_JB_MAGIC_SETJMP
998e03dd59SAndrew Turner#ifdef __ARM_EABI__
1008e03dd59SAndrew Turner	GOT_INITSYM(.Lsetjmp_got, .Lsetjmp_gotinit)
1018e03dd59SAndrew Turner.Lfpu_present:
1028e03dd59SAndrew Turner	.word	PIC_SYM(_libc_arm_fpu_present, GOTOFF)
1038e03dd59SAndrew Turner#endif /* __ARM_EABI__ */
104*f2e71517SIan LeporeEND(setjmp)
1052357939bSOlivier Houchard
1062357939bSOlivier Houchard.weak _C_LABEL(longjmp)
1072357939bSOlivier Houchard.set _C_LABEL(longjmp), _C_LABEL(__longjmp)
1082357939bSOlivier HouchardENTRY(__longjmp)
1098ed717deSAndrew Turner	ldr	r2, [r0]
1108ed717deSAndrew Turner	ldr	ip, .Lsetjmp_magic
1118e03dd59SAndrew Turner	bic	r3, r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
1128e03dd59SAndrew Turner	teq	r3, ip
1138ed717deSAndrew Turner	bne	.Lbotch
1142357939bSOlivier Houchard
1158ed717deSAndrew Turner	/* Restore the signal mask. */
1168ed717deSAndrew Turner	stmfd	sp!, {r0-r2, r14}
1178ed717deSAndrew Turner	mov	r2, #0x00000000
1188ed717deSAndrew Turner	add	r1, r0, #(_JB_SIGMASK * 4)	/* Signal mask */
1193d90a3cdSOlivier Houchard	mov	r0, #3				/* SIG_SETMASK */
1203d90a3cdSOlivier Houchard	bl	PIC_SYM(_C_LABEL(sigprocmask), PLT)
1218ed717deSAndrew Turner	ldmfd	sp!, {r0-r2, r14}
1222357939bSOlivier Houchard
1238e03dd59SAndrew Turner#ifdef __ARM_EABI__
1248e03dd59SAndrew Turner	tst	r2, #(_JB_MAGIC_SETJMP ^ _JB_MAGIC_SETJMP_VFP)
1258e03dd59SAndrew Turner						/* is this a VFP magic? */
1268e03dd59SAndrew Turner	beq	1f				/*   no, don't restore VFP */
1278e03dd59SAndrew Turner	add	ip, r0, #(_JB_REG_D8 * 4)
1288e03dd59SAndrew Turner	vldmia	ip, {d8-d15}
1298e03dd59SAndrew Turner	ldr	ip, [r0, #(_JB_REG_FPSCR * 4)]
1308e03dd59SAndrew Turner	vmsr	fpscr, ip
1318e03dd59SAndrew Turner1:
1328e03dd59SAndrew Turner#endif /* __ARM_EABI__ */
1338e03dd59SAndrew Turner
1348ed717deSAndrew Turner	add	r0, r0, #(_JB_REG_R4 * 4)
1352357939bSOlivier Houchard	/* Restore integer registers */
1362357939bSOlivier Houchard        ldmia	r0, {r4-r14}
1372357939bSOlivier Houchard
1382357939bSOlivier Houchard	/* Validate sp and r14 */
1392357939bSOlivier Houchard	teq	sp, #0
1402357939bSOlivier Houchard	teqne	r14, #0
1418ed717deSAndrew Turner	beq	.Lbotch
1422357939bSOlivier Houchard
1432357939bSOlivier Houchard	/* Set return value */
1448ed717deSAndrew Turner	movs	r0, r1
1452357939bSOlivier Houchard	moveq	r0, #0x00000001
14631489a9aSOlivier Houchard	RET
1472357939bSOlivier Houchard
1482357939bSOlivier Houchard	/* validation failed, die die die. */
1498ed717deSAndrew Turner.Lbotch:
1502357939bSOlivier Houchard	bl	PIC_SYM(_C_LABEL(longjmperror), PLT)
1512357939bSOlivier Houchard	bl	PIC_SYM(_C_LABEL(abort), PLT)
1522357939bSOlivier Houchard	b	. - 8		/* Cannot get here */
153*f2e71517SIan LeporeEND(__longjmp)
154