Blame sysdeps/unix/sysv/linux/ia64/setcontext.S

Packit 6c4009
/* Copyright (C) 2001-2018 Free Software Foundation, Inc.
Packit 6c4009
   This file is part of the GNU C Library.
Packit 6c4009
     Contributed by David Mosberger-Tang <davidm@hpl.hp.com>.
Packit 6c4009
Packit 6c4009
   The GNU C Library is free software; you can redistribute it and/or
Packit 6c4009
   modify it under the terms of the GNU Lesser General Public
Packit 6c4009
   License as published by the Free Software Foundation; either
Packit 6c4009
   version 2.1 of the License, or (at your option) any later version.
Packit 6c4009
Packit 6c4009
   The GNU C Library is distributed in the hope that it will be useful,
Packit 6c4009
   but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 6c4009
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 6c4009
   Lesser General Public License for more details.
Packit 6c4009
Packit 6c4009
   You should have received a copy of the GNU Lesser General Public
Packit 6c4009
   License along with the GNU C Library; if not, see
Packit 6c4009
   <http://www.gnu.org/licenses/>.  */
Packit 6c4009
Packit 6c4009
#include <sysdep.h>
Packit 6c4009
#include <features.h>
Packit 6c4009
Packit 6c4009
#include "ucontext_i.h"
Packit 6c4009
Packit 6c4009
/*  __setcontext (const ucontext_t *ucp)
Packit 6c4009
Packit 6c4009
  Restores the machine context in UCP and thereby resumes execution
Packit 6c4009
  in that context.
Packit 6c4009
Packit 6c4009
  This implementation in intended to be used for *synchronous* context
Packit 6c4009
  switches only.  Therefore, it does not have to restore anything
Packit 6c4009
  other than the PRESERVED state.  */
Packit 6c4009
Packit 6c4009
ENTRY(__setcontext)
Packit 6c4009
	.prologue
Packit 6c4009
	.body
Packit 6c4009
	alloc r11 = ar.pfs, 1, 0, 4, 0
Packit 6c4009
Packit 6c4009
	// sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL):
Packit 6c4009
Packit 6c4009
	mov r3 = SC_MASK
Packit 6c4009
	mov out0 = SIG_SETMASK
Packit 6c4009
	;;
Packit 6c4009
	add out1 = r3, in0
Packit 6c4009
	mov out2 = 0
Packit 6c4009
	mov out3 = 8	// sizeof kernel sigset_t
Packit 6c4009
Packit 6c4009
	invala
Packit 6c4009
	DO_CALL(__NR_rt_sigprocmask)
Packit 6c4009
	add r2 = SC_NAT, r32
Packit 6c4009
Packit 6c4009
	add r3 = SC_RNAT, r32			// r3 <- &sc_ar_rnat
Packit 6c4009
	add rPOS = SC_GR, r32			// rPOS <- &sc_gr[0]
Packit 6c4009
	;;
Packit 6c4009
	ld8 rNAT = [r2], (SC_BSP-SC_NAT)
Packit 6c4009
	extr.u rPOS = rPOS, 3, 6		// get NaT bit number for r0
Packit 6c4009
	;;
Packit 6c4009
	ld8 rBSP = [r2], (SC_UNAT-SC_BSP)
Packit 6c4009
	ld8 rRNAT = [r3], (SC_FPSR-SC_RNAT)
Packit 6c4009
	/*
Packit 6c4009
	 * Rotate NaT bits by rPOS positions to the left:
Packit 6c4009
	 */
Packit 6c4009
	sub rCPOS = 64, rPOS
Packit 6c4009
	;;
Packit 6c4009
	ld8 rUNAT = [r2], (SC_PFS-SC_UNAT)
Packit 6c4009
	ld8 rFPSR = [r3], (SC_LC-SC_FPSR)
Packit 6c4009
	shl rTMP = rNAT, rPOS
Packit 6c4009
	;;
Packit 6c4009
	ld8 rPFS = [r2], (SC_PR-SC_PFS)
Packit 6c4009
	ld8 rLC = [r3], (SC_BR+0*8-SC_LC)
Packit 6c4009
	shr.u rNAT = rNAT, rCPOS
Packit 6c4009
	;;
Packit 6c4009
	ld8 rPR = [r2], (SC_BR+1*8-SC_PR)
Packit 6c4009
	ld8 rB0 = [r3], 16
Packit 6c4009
	or rNAT = rNAT, rTMP
Packit 6c4009
	;;
Packit 6c4009
	ld8 rB1 = [r2], 16
Packit 6c4009
	ld8 rB2 = [r3], 16
Packit 6c4009
	;;
Packit 6c4009
	mov.m ar.unat = rNAT
Packit 6c4009
	mov.m rRSC = ar.rsc
Packit 6c4009
	;;
Packit 6c4009
	ld8 rB3 = [r2], 16
Packit 6c4009
	ld8 rB4 = [r3], (SC_GR+1*8-(SC_BR+4*8))
Packit 6c4009
	;;
Packit 6c4009
	ld8 rB5 = [r2], (SC_GR+4*8-(SC_BR+5*8))
Packit 6c4009
	ld8.fill r1 = [r3], (5*8 - 1*8)
Packit 6c4009
	;;
Packit 6c4009
	ld8.fill r4 = [r2], 16
Packit 6c4009
	ld8.fill r5 = [r3], 16
Packit 6c4009
	mov b0 = rB0
Packit 6c4009
	;;
Packit 6c4009
	ld8.fill r6 = [r2], 48
Packit 6c4009
	ld8.fill r7 = [r3], (SC_FR+2*16-(SC_GR+7*8))
Packit 6c4009
	;;
Packit 6c4009
	ld8.fill sp = [r2], (SC_FR+3*16-(SC_GR+12*8))
Packit 6c4009
	mov.m ar.fpsr = rFPSR
Packit 6c4009
	mov.i ar.pfs = rPFS
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f3 = [r2], 16
Packit 6c4009
	ldf.fill f2 = [r3], 48
Packit 6c4009
	mov b1 = rB1
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f4 = [r2], (16*16-4*16)
Packit 6c4009
	ldf.fill f5 = [r3], (17*16-5*16)
Packit 6c4009
	mov b2 = rB2
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f16 = [r2], 32
Packit 6c4009
	ldf.fill f17 = [r3], 32
Packit 6c4009
	mov b3 = rB3
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f18 = [r2], 32
Packit 6c4009
	ldf.fill f19 = [r3], 32
Packit 6c4009
	mov b4 = rB4
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f20 = [r2], 32
Packit 6c4009
	ldf.fill f21 = [r3], 32
Packit 6c4009
	mov b5 = rB5
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f22 = [r2], 32
Packit 6c4009
	ldf.fill f23 = [r3], 32
Packit 6c4009
	mov r8 = 0
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f24 = [r2], 32
Packit 6c4009
	ldf.fill f25 = [r3], 32
Packit 6c4009
	mov r9 = 0
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f26 = [r2], 32
Packit 6c4009
	ldf.fill f27 = [r3], 32
Packit 6c4009
	dep rTMP = 0, rRSC, 16, 14	// clear ar.rsc.loadrs
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f28 = [r2], 32
Packit 6c4009
	ldf.fill f29 = [r3], 32
Packit 6c4009
	and rTMP = ~0x3, rTMP		// clear ar.rsc.mode
Packit 6c4009
	;;
Packit 6c4009
	ldf.fill f30 = [r2], 32
Packit 6c4009
	ldf.fill f31 = [r3], 32
Packit 6c4009
	mov pr = rPR, -1
Packit 6c4009
	;;
Packit 6c4009
	mov.m ar.rsc = rTMP		// put RSE into enforced lazy mode
Packit 6c4009
	;;
Packit 6c4009
	loadrs				// drop dirty partition
Packit 6c4009
	;;
Packit 6c4009
	mov.m ar.bspstore = rBSP
Packit 6c4009
	mov.m ar.unat = rUNAT
Packit 6c4009
	mov.i ar.lc = rLC
Packit 6c4009
	;;
Packit 6c4009
	mov.m ar.rnat = rRNAT
Packit 6c4009
	mov.m ar.rsc = rRSC
Packit 6c4009
	ret
Packit 6c4009
END(__setcontext)
Packit 6c4009
Packit 6c4009
weak_alias (__setcontext, setcontext)