1/* Copyright (C) 2001-2022 Free Software Foundation, Inc. 2 This file is part of the GNU C Library. 3 4 The GNU C Library is free software; you can redistribute it and/or 5 modify it under the terms of the GNU Lesser General Public 6 License as published by the Free Software Foundation; either 7 version 2.1 of the License, or (at your option) any later version. 8 9 The GNU C Library is distributed in the hope that it will be useful, 10 but WITHOUT ANY WARRANTY; without even the implied warranty of 11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 12 Lesser General Public License for more details. 13 14 You should have received a copy of the GNU Lesser General Public 15 License along with the GNU C Library; if not, see 16 <https://www.gnu.org/licenses/>. */ 17 18#include <sysdep.h> 19#include <features.h> 20 21#include "ucontext_i.h" 22 23/* __getcontext (ucontext_t *ucp) 24 25 Saves the machine context in UCP such that when it is activated, 26 it appears as if __getcontext() returned again. The only difference 27 is that on a first return, r9 contains 1 and on a subsequent 28 return, it contains 0. 29 30 This implementation in intended to be used for *synchronous* context 31 switches only. Therefore, it does not have to save anything 32 other than the PRESERVED state. */ 33 34ENTRY(__getcontext) 35 .prologue 36 .body 37 alloc r11 = ar.pfs, 1, 0, 4, 0 38 39 // sigprocmask (SIG_BLOCK, NULL, &sc->sc_mask): 40 41 mov r3 = SC_MASK 42 mov out0 = SIG_BLOCK 43 44 flushrs // save dirty partition on rbs 45 mov out1 = 0 46 add out2 = r3, in0 47 48 mov out3 = 8 // sizeof kernel sigset_t 49 DO_CALL(__NR_rt_sigprocmask) 50 51 mov.m rFPSR = ar.fpsr 52 mov.m rRSC = ar.rsc 53 add r2 = SC_GR+1*8, r32 54 ;; 55 mov.m rBSP = ar.bsp 56 .prologue 57 .save ar.unat, rUNAT 58 mov.m rUNAT = ar.unat 59 .body 60 add r3 = SC_GR+4*8, r32 61 ;; 62 63.mem.offset 0,0; st8.spill [r2] = r1, (5*8 - 1*8) 64.mem.offset 8,0; st8.spill [r3] = r4, 16 65 mov rPFS = r11 66 ;; 67.mem.offset 0,0; st8.spill [r2] = r5, 16 68.mem.offset 8,0; st8.spill [r3] = r6, 48 69 and rTMP = ~0x3, rRSC 70 ;; 71.mem.offset 0,0; st8.spill [r2] = r7, (SC_FR+2*16-(SC_GR+7*8)) 72.mem.offset 8,0; st8.spill [r3] = sp, (SC_FR+3*16-(SC_GR+12*8)) 73 ;; 74 mov.m ar.rsc = rTMP // put RSE into enforced lazy mode 75 mov.m rNAT = ar.unat 76 mov.i rLC = ar.lc 77 ;; 78 mov.m rRNAT = ar.rnat 79 mov.m ar.rsc = rRSC // restore RSE mode 80 mov rPR = pr 81 82 /* 83 * Rotate NaT bits by rPOS positions to the right: 84 */ 85 stf.spill [r2] = f2, 32 86 stf.spill [r3] = f3, 32 87 add rPOS = SC_GR, r32 // rPOS <- &sc_gr[0] 88 ;; 89 stf.spill [r2] = f4, (16*16-4*16) 90 stf.spill [r3] = f5, (17*16-5*16) 91 extr.u rPOS = rPOS, 3, 6 // get NaT bit number for r0 92 ;; 93 stf.spill [r2] = f16, 32 94 stf.spill [r3] = f17, 32 95 sub rCPOS = 64, rPOS 96 ;; 97 stf.spill [r2] = f18, 32 98 stf.spill [r3] = f19, 32 99 shr.u rTMP = rNAT, rPOS 100 ;; 101 stf.spill [r2] = f20, 32 102 stf.spill [r3] = f21, 32 103 shl rNAT = rNAT, rCPOS 104 ;; 105 stf.spill [r2] = f22, 32 106 stf.spill [r3] = f23, 32 107 or rNAT = rNAT, rTMP 108 ;; 109 stf.spill [r2] = f24, 32 110 stf.spill [r3] = f25, 32 111 mov r8 = 0 112 ;; 113 stf.spill [r2] = f26, 32 114 stf.spill [r3] = f27, 32 115 mov r9 = 1 116 ;; 117 stf.spill [r2] = f28, 32 118 stf.spill [r3] = f29, 32 119 mov rB0 = b0 120 ;; 121 stf.spill [r2] = f30, 32 122 stf.spill [r3] = f31, 32 123 mov rB1 = b1 124 ;; 125 mov ar.unat = rUNAT // we're done spilling integer regs; restore caller's UNaT 126 add r2 = SC_NAT, r32 127 add r3 = SC_BSP, r32 128 ;; 129 st8 [r2] = rNAT, (SC_RNAT-SC_NAT) 130 st8 [r3] = rBSP, (SC_UNAT-SC_BSP) 131 mov rB2 = b2 132 ;; 133 st8 [r2] = rRNAT, (SC_FPSR-SC_RNAT) 134 st8 [r3] = rUNAT, (SC_PFS-SC_UNAT) 135 mov rB3 = b3 136 ;; 137 st8 [r2] = rFPSR, (SC_LC-SC_FPSR) 138 st8 [r3] = rPFS, (SC_PR-SC_PFS) 139 mov rB4 = b4 140 ;; 141 st8 [r2] = rLC, (SC_BR+0*8-SC_LC) 142 st8 [r3] = rPR, (SC_BR+1*8-SC_PR) 143 mov rB5 = b5 144 ;; 145 st8 [r2] = rB0, 16 146 st8 [r3] = rB1, 16 147 ;; 148 st8 [r2] = rB2, 16 149 st8 [r3] = rB3, 16 150 ;; 151 st8 [r2] = rB4 152 st8 [r3] = rB5 153 ret 154END(__getcontext) 155 156weak_alias (__getcontext, getcontext) 157