| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181 | /* Modify saved context.   Copyright (C) 2009 Free Software Foundation, Inc.   This file is part of the GNU C Library.   Contributed by Maciej W. Rozycki <macro@codesourcery.com>.   The GNU C Library is free software; you can redistribute it and/or   modify it under the terms of the GNU Lesser General Public   License as published by the Free Software Foundation; either   version 2.1 of the License, or (at your option) any later version.   The GNU C Library is distributed in the hope that it will be useful,   but WITHOUT ANY WARRANTY; without even the implied warranty of   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU   Lesser General Public License for more details.   You should have received a copy of the GNU Lesser General Public   License along with the GNU C Library.  If not, see   <http://www.gnu.org/licenses/>.  */#include <sysdep.h>#include <sys/asm.h>#include <sys/fpregdef.h>#include <sys/regdef.h>#include "ucontext_i.h"/* int makecontext (ucontext_t *ucp, (void *func) (), int argc, ...) */	.textLOCALSZ = 0ARGSZ = 0MASK = 0x00000000#ifdef __PIC__LOCALSZ = 1						/* save gp */#endif#if _MIPS_SIM != _ABIO32ARGSZ = 5						/* save a3-a7 */# ifdef __PIC__MASK = 0x10000000# endif#endifFRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASKGPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG)#if _MIPS_SIM != _ABIO32A3OFF = FRAMESZ - (5 * SZREG)				/* callee-allocated */A4OFF = FRAMESZ - (4 * SZREG)A5OFF = FRAMESZ - (3 * SZREG)A6OFF = FRAMESZ - (2 * SZREG)A7OFF = FRAMESZ - (1 * SZREG)NARGREGS = 8#elseA3OFF = FRAMESZ + (3 * SZREG)				/* caller-allocated */NARGREGS = 4#endifNESTED (__makecontext, FRAMESZ, ra)	.mask	MASK, -(ARGSZ * SZREG)	.fmask	0x00000000, 098:#ifdef __PIC__	SETUP_GP#endif	PTR_ADDIU sp, -FRAMESZ#ifdef __PIC__	SETUP_GP64 (GPOFF, __makecontext)	SAVE_GP (GPOFF)#endif	/* Store args to be passed.  */	REG_S	a3, A3OFF(sp)#if _MIPS_SIM != _ABIO32	REG_S	a4, A4OFF(sp)	REG_S	a5, A5OFF(sp)	REG_S	a6, A6OFF(sp)	REG_S	a7, A7OFF(sp)#endif	/* Store a magic flag.  */	li	v1, 1	REG_S	v1, (0 * SZREG + MCONTEXT_GREGS)(a0)	/* zero */	/* Set up the stack.  */	PTR_L	t0, STACK_SP(a0)	PTR_L	t2, STACK_SIZE(a0)	PTR_ADDIU t1, sp, A3OFF	PTR_ADDU t0, t2	and	t0, ALMASK	blez	a2, 2f					/* no arguments */	/* Store register arguments.  */	PTR_ADDIU t2, a0, MCONTEXT_GREGS + 4 * SZREG	move	t3, zero0:	addiu	t3, 1	REG_L	v1, (t1)	PTR_ADDIU t1, SZREG	REG_S	v1, (t2)	PTR_ADDIU t2, SZREG	bgeu	t3, a2, 2f				/* all done */	bltu	t3, NARGREGS, 0b			/* next */	/* Make room for stack arguments.  */	PTR_SUBU t2, a2, t3	PTR_SLL	t2, 3	PTR_SUBU t0, t2	and	t0, ALMASK	/* Store stack arguments.  */	move	t2, t01:	addiu	t3, 1	REG_L	v1, (t1)	PTR_ADDIU t1, SZREG	REG_S	v1, (t2)	PTR_ADDIU t2, SZREG	bltu	t3, a2, 1b				/* next */2:#if _MIPS_SIM == _ABIO32	/* Make room for a0-a3 storage.  */	PTR_ADDIU t0, -(NARGSAVE * SZREG)#endif	PTR_L	v1, UCONTEXT_LINK(a0)#ifdef __PIC__	PTR_ADDIU t9, 99f - 98b#else	PTR_LA	t9, 99f#endif	REG_S	t0, (29 * SZREG + MCONTEXT_GREGS)(a0)	/* sp */	REG_S	v1, (16 * SZREG + MCONTEXT_GREGS)(a0)	/* s0 */#ifdef __PIC__	REG_S	gp, (17 * SZREG + MCONTEXT_GREGS)(a0)	/* s1 */#endif	REG_S	t9, (31 * SZREG + MCONTEXT_GREGS)(a0)	/* ra */	REG_S	a1, MCONTEXT_PC(a0)#ifdef __PIC__	RESTORE_GP64	PTR_ADDIU sp, FRAMESZ#endif	jr	ra99:#ifdef __PIC__	move	gp, s1#endif	move	a0, zero	beqz	s0, 0f	/* setcontext (ucp) */	move	a0, s0#ifdef __PIC__	PTR_LA	t9, JUMPTARGET (__setcontext)	jalr	t9# if _MIPS_SIM == _ABIO32	move	gp, s1# endif#else	jal	JUMPTARGET (__setcontext)#endif	move	a0, v00:	/* exit (a0) */#ifdef __PIC__	PTR_LA	t9, HIDDEN_JUMPTARGET (exit)	jalr	t9#else	jal	HIDDEN_JUMPTARGET (exit)#endif	/* You don't exist, you won't feel anything.  */1:	lb	zero, (zero)	b	1bPSEUDO_END (__makecontext)weak_alias (__makecontext, makecontext)
 |