summaryrefslogtreecommitdiff
path: root/ports/sysdeps/unix/sysv/linux/ia64/setcontext.S
diff options
context:
space:
mode:
Diffstat (limited to 'ports/sysdeps/unix/sysv/linux/ia64/setcontext.S')
-rw-r--r--ports/sysdeps/unix/sysv/linux/ia64/setcontext.S152
1 files changed, 152 insertions, 0 deletions
diff --git a/ports/sysdeps/unix/sysv/linux/ia64/setcontext.S b/ports/sysdeps/unix/sysv/linux/ia64/setcontext.S
new file mode 100644
index 0000000000..14091fefa8
--- /dev/null
+++ b/ports/sysdeps/unix/sysv/linux/ia64/setcontext.S
@@ -0,0 +1,152 @@
+/* Copyright (C) 2001, 2003 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+ Contributed by David Mosberger-Tang <davidm@hpl.hp.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 <features.h>
+
+#include "ucontext_i.h"
+
+/* __setcontext (const ucontext_t *ucp)
+
+ Restores the machine context in UCP and thereby resumes execution
+ in that context.
+
+ This implementation in intended to be used for *synchronous* context
+ switches only. Therefore, it does not have to restore anything
+ other than the PRESERVED state. */
+
+ENTRY(__setcontext)
+ .prologue
+ .body
+ alloc r11 = ar.pfs, 1, 0, 4, 0
+
+ // sigprocmask (SIG_SETMASK, &sc->sc_mask, NULL):
+
+ mov r3 = SC_MASK
+ mov out0 = SIG_SETMASK
+ ;;
+ add out1 = r3, in0
+ mov out2 = 0
+ mov out3 = 8 // sizeof kernel sigset_t
+
+ invala
+ DO_CALL(__NR_rt_sigprocmask)
+ add r2 = SC_NAT, r32
+
+ add r3 = SC_RNAT, r32 // r3 <- &sc_ar_rnat
+ add rPOS = SC_GR, r32 // rPOS <- &sc_gr[0]
+ ;;
+ ld8 rNAT = [r2], (SC_BSP-SC_NAT)
+ extr.u rPOS = rPOS, 3, 6 // get NaT bit number for r0
+ ;;
+ ld8 rBSP = [r2], (SC_UNAT-SC_BSP)
+ ld8 rRNAT = [r3], (SC_FPSR-SC_RNAT)
+ /*
+ * Rotate NaT bits by rPOS positions to the left:
+ */
+ sub rCPOS = 64, rPOS
+ ;;
+ ld8 rUNAT = [r2], (SC_PFS-SC_UNAT)
+ ld8 rFPSR = [r3], (SC_LC-SC_FPSR)
+ shl rTMP = rNAT, rPOS
+ ;;
+ ld8 rPFS = [r2], (SC_PR-SC_PFS)
+ ld8 rLC = [r3], (SC_BR+0*8-SC_LC)
+ shr.u rNAT = rNAT, rCPOS
+ ;;
+ ld8 rPR = [r2], (SC_BR+1*8-SC_PR)
+ ld8 rB0 = [r3], 16
+ or rNAT = rNAT, rTMP
+ ;;
+ ld8 rB1 = [r2], 16
+ ld8 rB2 = [r3], 16
+ ;;
+ mov.m ar.unat = rNAT
+ mov.m rRSC = ar.rsc
+ ;;
+ ld8 rB3 = [r2], 16
+ ld8 rB4 = [r3], (SC_GR+1*8-(SC_BR+4*8))
+ ;;
+ ld8 rB5 = [r2], (SC_GR+4*8-(SC_BR+5*8))
+ ld8.fill r1 = [r3], (5*8 - 1*8)
+ ;;
+ ld8.fill r4 = [r2], 16
+ ld8.fill r5 = [r3], 16
+ mov b0 = rB0
+ ;;
+ ld8.fill r6 = [r2], 48
+ ld8.fill r7 = [r3], (SC_FR+2*16-(SC_GR+7*8))
+ ;;
+ ld8.fill sp = [r2], (SC_FR+3*16-(SC_GR+12*8))
+ mov.m ar.fpsr = rFPSR
+ mov.i ar.pfs = rPFS
+ ;;
+ ldf.fill f3 = [r2], 16
+ ldf.fill f2 = [r3], 48
+ mov b1 = rB1
+ ;;
+ ldf.fill f4 = [r2], (16*16-4*16)
+ ldf.fill f5 = [r3], (17*16-5*16)
+ mov b2 = rB2
+ ;;
+ ldf.fill f16 = [r2], 32
+ ldf.fill f17 = [r3], 32
+ mov b3 = rB3
+ ;;
+ ldf.fill f18 = [r2], 32
+ ldf.fill f19 = [r3], 32
+ mov b4 = rB4
+ ;;
+ ldf.fill f20 = [r2], 32
+ ldf.fill f21 = [r3], 32
+ mov b5 = rB5
+ ;;
+ ldf.fill f22 = [r2], 32
+ ldf.fill f23 = [r3], 32
+ mov r8 = 0
+ ;;
+ ldf.fill f24 = [r2], 32
+ ldf.fill f25 = [r3], 32
+ mov r9 = 0
+ ;;
+ ldf.fill f26 = [r2], 32
+ ldf.fill f27 = [r3], 32
+ dep rTMP = 0, rRSC, 16, 14 // clear ar.rsc.loadrs
+ ;;
+ ldf.fill f28 = [r2], 32
+ ldf.fill f29 = [r3], 32
+ and rTMP = ~0x3, rTMP // clear ar.rsc.mode
+ ;;
+ ldf.fill f30 = [r2], 32
+ ldf.fill f31 = [r3], 32
+ mov pr = rPR, -1
+ ;;
+ mov.m ar.rsc = rTMP // put RSE into enforced lazy mode
+ ;;
+ loadrs // drop dirty partition
+ ;;
+ mov.m ar.bspstore = rBSP
+ mov.m ar.unat = rUNAT
+ mov.i ar.lc = rLC
+ ;;
+ mov.m ar.rnat = rRNAT
+ mov.m ar.rsc = rRSC
+ ret
+END(__setcontext)
+
+weak_alias (__setcontext, setcontext)