mirror of
				https://sourceware.org/git/glibc.git
				synced 2025-10-30 10:45:40 +03:00 
			
		
		
		
	
		
			
				
	
	
		
			192 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
			
		
		
	
	
			192 lines
		
	
	
		
			4.0 KiB
		
	
	
	
		
			ArmAsm
		
	
	
	
	
	
| /* Modify saved context.
 | |
|    Copyright (C) 2009-2015 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, ...) */
 | |
| 
 | |
| 	.text
 | |
| 	.set	nomips16
 | |
| LOCALSZ = 0
 | |
| ARGSZ = 0
 | |
| MASK = 0x00000000
 | |
| #ifdef __PIC__
 | |
| LOCALSZ = 1						/* save gp */
 | |
| #endif
 | |
| #if _MIPS_SIM != _ABIO32
 | |
| ARGSZ = 5						/* save a3-a7 */
 | |
| # ifdef __PIC__
 | |
| MASK = 0x10000000
 | |
| # endif
 | |
| #endif
 | |
| FRAMESZ = (((ARGSZ + LOCALSZ) * SZREG) + ALSZ) & ALMASK
 | |
| GPOFF = FRAMESZ - ((ARGSZ + 1) * SZREG)
 | |
| #if _MIPS_SIM != _ABIO32
 | |
| A3OFF = FRAMESZ - (5 * SZREG)				/* callee-allocated */
 | |
| A4OFF = FRAMESZ - (4 * SZREG)
 | |
| A5OFF = FRAMESZ - (3 * SZREG)
 | |
| A6OFF = FRAMESZ - (2 * SZREG)
 | |
| A7OFF = FRAMESZ - (1 * SZREG)
 | |
| NARGREGS = 8
 | |
| #else
 | |
| A3OFF = FRAMESZ + (3 * SZREG)				/* caller-allocated */
 | |
| NARGREGS = 4
 | |
| #endif
 | |
| 
 | |
| NESTED (__makecontext, FRAMESZ, ra)
 | |
| 	.mask	MASK, -(ARGSZ * SZREG)
 | |
| 	.fmask	0x00000000, 0
 | |
| 
 | |
| 98:
 | |
| #ifdef __PIC__
 | |
| 	SETUP_GP
 | |
| #endif
 | |
| 
 | |
| 	PTR_ADDIU sp, -FRAMESZ
 | |
| 	cfi_adjust_cfa_offset (FRAMESZ)
 | |
| 
 | |
| #ifdef __PIC__
 | |
| 	SETUP_GP64_STACK (GPOFF, __makecontext)
 | |
| 	SAVE_GP (GPOFF)
 | |
| #endif
 | |
| 
 | |
| #ifdef PROF
 | |
| 	.set	noat
 | |
| 	move	AT, ra
 | |
| 	jal	_mcount
 | |
| 	.set	at
 | |
| #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, zero
 | |
| 0:
 | |
| 	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, t0
 | |
| 1:
 | |
| 	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_STACK
 | |
| 	PTR_ADDIU sp, FRAMESZ
 | |
| 	cfi_adjust_cfa_offset (-FRAMESZ)
 | |
| #endif
 | |
| 	jr	ra
 | |
| 
 | |
| 99:
 | |
| #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, v0
 | |
| 
 | |
| 0:
 | |
| 	/* 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	1b
 | |
| PSEUDO_END (__makecontext)
 | |
| 
 | |
| weak_alias (__makecontext, makecontext)
 |