1// 2// Copyright (c) 1999, 2000 3// Intel Corporation. 4// All rights reserved. 5// 6// Redistribution and use in source and binary forms, with or without 7// modification, are permitted provided that the following conditions 8// are met: 9// 10// 1. Redistributions of source code must retain the above copyright 11// notice, this list of conditions and the following disclaimer. 12// 13// 2. Redistributions in binary form must reproduce the above copyright 14// notice, this list of conditions and the following disclaimer in the 15// documentation and/or other materials provided with the distribution. 16// 17// 3. All advertising materials mentioning features or use of this software 18// must display the following acknowledgement: 19// 20// This product includes software developed by Intel Corporation and 21// its contributors. 22// 23// 4. Neither the name of Intel Corporation or its contributors may be 24// used to endorse or promote products derived from this software 25// without specific prior written permission. 26// 27// THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 28// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30// ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 31// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 37// THE POSSIBILITY OF SUCH DAMAGE. 38// 39// 40 41// 42// Module Name: 43// 44// setjmp.s 45// 46// Abstract: 47// 48// Contains an implementation of setjmp and longjmp for the 49// IA-64 architecture. 50 51 .file "setjmp.s" 52 53#include <machine/asm.h> 54__FBSDID("$FreeBSD$"); 55 56#define LOCORE 57#include <machine/setjmp.h> 58 59// int _setjmp(struct jmp_buffer *) 60// 61// Setup a non-local goto. 62// 63// Description: 64// 65// SetJump stores the current register set in the area pointed to 66// by "save". It returns zero. Subsequent calls to "LongJump" will 67// restore the registers and return non-zero to the same location. 68// 69// On entry, r32 contains the pointer to the jmp_buffer 70// 71 72ENTRY(_setjmp, 1) 73 add r10 = J_PREDS, r32 // skip Unats & pfs save area 74 add r11 = J_BSP, r32 75 // 76 // save immediate context 77 // 78 mov r2 = ar.bsp // save backing store pointer 79 mov r3 = pr // save predicates 80 flushrs 81 ;; 82 // 83 // save user Unat register 84 // 85 mov r16 = ar.lc // save loop count register 86 mov r14 = ar.unat // save user Unat register 87 88 st8 [r10] = r3, J_LC-J_PREDS 89 st8 [r11] = r2, J_R4-J_BSP 90 ;; 91 st8 [r10] = r16, J_R5-J_LC 92 st8 [r32] = r14, J_NATS // Note: Unat at the 93 // beginning of the save area 94 mov r15 = ar.pfs 95 ;; 96 // 97 // save preserved general registers & NaT's 98 // 99 .mem.offset 0,0 100 st8.spill [r11] = r4, J_R6-J_R4 101 .mem.offset 8,0 102 st8.spill [r10] = r5, J_R7-J_R5 103 ;; 104 .mem.offset 16,0 105 st8.spill [r11] = r6, J_SP-J_R6 106 .mem.offset 24,0 107 st8.spill [r10] = r7, J_F3-J_R7 108 ;; 109 st8.spill [r11] = sp, J_F2-J_SP 110 mov r16 = ar.rsc 111 ;; 112 // 113 // save spilled Unat and pfs registers 114 // 115 mov r2 = ar.unat // save Unat register after spill 116 mov ar.rsc = r0 117 ;; 118 st8 [r32] = r2, J_PFS-J_NATS // save unat for spilled regs 119 mov r17 = ar.rnat 120 ;; 121 st8 [r32] = r15, J_RNAT-J_PFS // save pfs 122 mov ar.rsc = r16 123 // 124 // save floating registers 125 // 126 stf.spill [r11] = f2, J_F4-J_F2 127 stf.spill [r10] = f3, J_F5-J_F3 128 ;; 129 stf.spill [r11] = f4, J_F16-J_F4 130 stf.spill [r10] = f5, J_F17-J_F5 131 ;; 132 stf.spill [r11] = f16, J_F18-J_F16 133 stf.spill [r10] = f17, J_F19-J_F17 134 ;; 135 stf.spill [r11] = f18, J_F20-J_F18 136 stf.spill [r10] = f19, J_F21-J_F19 137 ;; 138 stf.spill [r11] = f20, J_F22-J_F20 139 stf.spill [r10] = f21, J_F23-J_F21 140 ;; 141 stf.spill [r11] = f22, J_F24-J_F22 142 stf.spill [r10] = f23, J_F25-J_F23 143 ;; 144 stf.spill [r11] = f24, J_F26-J_F24 145 stf.spill [r10] = f25, J_F27-J_F25 146 ;; 147 stf.spill [r11] = f26, J_F28-J_F26 148 stf.spill [r10] = f27, J_F29-J_F27 149 ;; 150 stf.spill [r11] = f28, J_F30-J_F28 151 stf.spill [r10] = f29, J_F31-J_F29 152 ;; 153 stf.spill [r11] = f30, J_FPSR-J_F30 154 stf.spill [r10] = f31, J_B0-J_F31 // size of f31 + fpsr 155 ;; 156 st8 [r32] = r17 157 // 158 // save FPSR register & branch registers 159 // 160 mov r2 = ar.fpsr // save fpsr register 161 mov r3 = b0 162 ;; 163 st8 [r11] = r2, J_B1-J_FPSR 164 st8 [r10] = r3, J_B2-J_B0 165 mov r2 = b1 166 mov r3 = b2 167 ;; 168 st8 [r11] = r2, J_B3-J_B1 169 st8 [r10] = r3, J_B4-J_B2 170 mov r2 = b3 171 mov r3 = b4 172 ;; 173 st8 [r11] = r2, J_B5-J_B3 174 st8 [r10] = r3 175 mov r2 = b5 176 ;; 177 st8 [r11] = r2 178 ;; 179 // 180 // return 181 // 182 mov r8 = r0 // return 0 from setjmp 183 mov ar.unat = r14 // restore unat 184 br.ret.sptk b0 185 186END(_setjmp) 187 188 189// 190// void _longjmp(struct jmp_buffer *, int val) 191// 192// Perform a non-local goto. 193// 194// Description: 195// 196// LongJump initializes the register set to the values saved by a 197// previous 'SetJump' and jumps to the return location saved by that 198// 'SetJump'. This has the effect of unwinding the stack and returning 199// for a second time to the 'SetJump'. 200// 201 202 WEAK_ALIAS(_longjmp,___longjmp) 203ENTRY(___longjmp, 2) 204 mov r14 = ar.rsc // get user RSC conf 205 mov r8 = r33 // return value 206 add r10 = J_PFS, r32 // get address of pfs 207 ;; 208 mov ar.rsc = r0 209 add r11 = J_NATS, r32 210 add r17 = J_RNAT, r32 211 ;; 212 ld8 r15 = [r10], J_BSP-J_PFS // get pfs 213 ld8 r2 = [r11], J_LC-J_NATS // get unat for spilled regs 214 mov r31 = r32 215 ;; 216 loadrs 217 mov ar.unat = r2 218 cmp.eq p6,p0=0,r8 // Return value 0? 219 ;; 220 ld8 r16 = [r10], J_PREDS-J_BSP // get backing store pointer 221 ld8 r17 = [r17] // ar.rnat 222 mov ar.pfs = r15 223 ;; 224 mov ar.bspstore = r16 225(p6) add r8 = 1, r0 226 ;; 227 mov ar.rnat = r17 228 mov ar.rsc = r14 // restore RSC conf 229 230 ld8 r3 = [r11], J_R4-J_LC // get lc register 231 ld8 r2 = [r10], J_R5-J_PREDS // get predicates 232 ;; 233 mov pr = r2, -1 234 mov ar.lc = r3 235 // 236 // restore preserved general registers & NaT's 237 // 238 ld8.fill r4 = [r11], J_R6-J_R4 239 ;; 240 ld8.fill r5 = [r10], J_R7-J_R5 241 ld8.fill r6 = [r11], J_SP-J_R6 242 ;; 243 ld8.fill r7 = [r10], J_F2-J_R7 244 ld8.fill sp = [r11], J_F3-J_SP 245 ;; 246 // 247 // restore floating registers 248 // 249 ldf.fill f2 = [r10], J_F4-J_F2 250 ldf.fill f3 = [r11], J_F5-J_F3 251 ;; 252 ldf.fill f4 = [r10], J_F16-J_F4 253 ldf.fill f5 = [r11], J_F17-J_F5 254 ;; 255 ldf.fill f16 = [r10], J_F18-J_F16 256 ldf.fill f17 = [r11], J_F19-J_F17 257 ;; 258 ldf.fill f18 = [r10], J_F20-J_F18 259 ldf.fill f19 = [r11], J_F21-J_F19 260 ;; 261 ldf.fill f20 = [r10], J_F22-J_F20 262 ldf.fill f21 = [r11], J_F23-J_F21 263 ;; 264 ldf.fill f22 = [r10], J_F24-J_F22 265 ldf.fill f23 = [r11], J_F25-J_F23 266 ;; 267 ldf.fill f24 = [r10], J_F26-J_F24 268 ldf.fill f25 = [r11], J_F27-J_F25 269 ;; 270 ldf.fill f26 = [r10], J_F28-J_F26 271 ldf.fill f27 = [r11], J_F29-J_F27 272 ;; 273 ldf.fill f28 = [r10], J_F30-J_F28 274 ldf.fill f29 = [r11], J_F31-J_F29 275 ;; 276 ldf.fill f30 = [r10], J_FPSR-J_F30 277 ldf.fill f31 = [r11], J_B0-J_F31 ;; 278 279 // 280 // restore branch registers and fpsr 281 // 282 ld8 r16 = [r10], J_B1-J_FPSR // get fpsr 283 ld8 r17 = [r11], J_B2-J_B0 // get return pointer 284 ;; 285 mov ar.fpsr = r16 286 mov b0 = r17 287 ld8 r2 = [r10], J_B3-J_B1 288 ld8 r3 = [r11], J_B4-J_B2 289 ;; 290 mov b1 = r2 291 mov b2 = r3 292 ld8 r2 = [r10], J_B5-J_B3 293 ld8 r3 = [r11] 294 ;; 295 mov b3 = r2 296 mov b4 = r3 297 ld8 r2 = [r10] 298 ld8 r21 = [r31] // get user unat 299 ;; 300 mov b5 = r2 301 mov ar.unat = r21 302 303 // 304 // invalidate ALAT 305 // 306 invala ;; 307 308 br.ret.sptk b0 309 310END(___longjmp) 311