	.file	"sigsetjmp.s"
/*
 * $Copyright:	$
 * Copyright (c) 1984, 1985, 1986, 1987, 1988, 1989, 1990 
 * Sequent Computer Systems, Inc.   All rights reserved.
 *  
 * This software is furnished under a license and may be used
 * only in accordance with the terms of that license and with the
 * inclusion of the above copyright notice.   This software may not
 * be provided or otherwise made available to, or used by, any
 * other person.  No title to or ownership of the software is
 * hereby transferred.
 *
 */

/*	Copyright (c) 1984 AT&T	*/
/*	All Rights Reserved	*/

/*	THIS IS UNPUBLISHED PROPRIETARY SOURCE CODE OF AT&T	*/
/*	The copyright notice above does not evidence any	*/
/*	actual or intended publication of such source code.	*/

	.ident	"@(#)$Header: sigsetjmp.s 1.6 90/09/04 $"

/* C library -- sigsetjmp, siglongjmp	*/

/*	siglongjmp(a,v)						*/
/* will generate a "return(v)" from 				*/
/* the last call to						*/
/* 	sigsetjmp(a,m)						*/
/* by restoring ip, sp, bp, bx, si, and di  and signal mask if  */
/* m was set, from 'a' and doing a return			*/

/* entry    reg		offset		*/
/* env[0] = %ebx	 0		*/
/* env[1] = %esi	 4		*/
/* env[2] = %edi	 8		*/
/* env[3] = %ebp	 12		*/
/* env[4] = %esp	 16		*/
/* env[5] = %eip	 20		*/
/* env[6] = arg1  	 24		*/
/* env[7] = (sigset_t)	 28		*/

#include "sys.s"
#define INLIBC
#include "sys/signal.h"



/* POSIX requires that sigsetjmp be a macro defined in setjmp.h.	*/
/* The definition is:
/*    #define sigsetjmp(env, savemask)	_sigsetjmp((env), (savemask))	*/
/* However, for the sake of compatibility, we will keep it		*/
/* as a library function.  Note that we also want to force the macro    */
/* to become a function call since in the future we may implement shared*/
/* libraries.  Keeping it as a function call could provide a bit more   */
/* backwards compatibility if we ever changed the stack frame.		*/

ENTRY(sigsetjmp)
	movl	SPARG0,%eax
	pushl	%eax
	movl	SPARG1,%eax
	pushl	%eax
	call	_sigsetjmp
	addl	$8,%esp
	ret

ENTRY(_sigsetjmp)
	movl	SPARG0,%eax	/* %eax = buffer address */
	movl	%ebx,(%eax)	/* save %ebx */
	movl	%esi,4(%eax)	/*      %esi */
	movl	%edi,8(%eax)	/*      %edi */
	movl	%ebp,12(%eax)	/*      %ebp */
	movl	SPARG1,%edx	/* signal mask flag*/
	movl	%edx,24(%eax)	/* save signal mask */
	cmpl	$0,%edx
	je	.s0
	leal	28(%eax),%eax
	pushl	%eax
	pushl	$0
	pushl	$SIG_SETMASK
	call	sigprocmask	/* sigprocmask(SIG_SETMASK, 0, &set ); */
	addl	$12,%esp
	movl	SPARG0,%eax	/* restore %eax = buffer address */
.s0:
	popl	%edx		/* %edx = return address */
	movl	%esp,16(%eax)	/* save callers %esp */
	movl	%edx,20(%eax)	/* save callers %eip */
	xorl	%eax,%eax	/* return zero */
	jmp	*%edx

ENTRY(siglongjmp)
	movl	SPARG0,%edx	/* %edx = buffer address  */
	cmpl	$0,24(%edx)	/* if (sigset) */
	je	.ret0
	pushl	$0
	leal	28(%edx),%eax
	pushl	%eax
	pushl	$SIG_SETMASK
	call	sigprocmask	/* sigprocmask(SIG_SETMASK, &set, 0 ); */
	addl	$12,%esp
	movl	SPARG0,%edx	/* %edx = buffer address  */
.ret0:
	movl	SPARG1,%eax	/* %eax = return value */
	cmpl	12(%edx),%ebp	/* see if called from same procedure */
	je	.sameproc	/* if so, don't restore register variables */
	movl	(%edx),%ebx	/* restore %ebx */
	movl	4(%edx),%esi	/* 	   %esi */
	movl	8(%edx),%edi	/* 	   %edi */
	movl	12(%edx),%ebp	/*	   %ebp */
.sameproc:
	movl	16(%edx),%esp	/*	   %esp */
	testl	%eax,%eax	/* if v != 0 */
	jz	.ret1		/*	return v */
	jmp	*20(%edx)	/* return to caller */
.ret1:
	incl	%eax		/* else return 1 */
	jmp	*20(%edx)	/* return to caller */
