_setjmp.S revision 111897
1255253Ssjg// 2236769Sobrien// Copyright (c) 1999, 2000 3236769Sobrien// Intel Corporation. 4236769Sobrien// All rights reserved. 5236769Sobrien// 6236769Sobrien// Redistribution and use in source and binary forms, with or without 7236769Sobrien// modification, are permitted provided that the following conditions 8236769Sobrien// are met: 9236769Sobrien// 10236769Sobrien// 1. Redistributions of source code must retain the above copyright 11236769Sobrien// notice, this list of conditions and the following disclaimer. 12236769Sobrien// 13236769Sobrien// 2. Redistributions in binary form must reproduce the above copyright 14236769Sobrien// notice, this list of conditions and the following disclaimer in the 15236769Sobrien// documentation and/or other materials provided with the distribution. 16236769Sobrien// 17236769Sobrien// 3. All advertising materials mentioning features or use of this software 18236769Sobrien// must display the following acknowledgement: 19236769Sobrien// 20236769Sobrien// This product includes software developed by Intel Corporation and 21236769Sobrien// its contributors. 22236769Sobrien// 23236769Sobrien// 4. Neither the name of Intel Corporation or its contributors may be 24236769Sobrien// used to endorse or promote products derived from this software 25236769Sobrien// without specific prior written permission. 26236769Sobrien// 27236769Sobrien// THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION AND CONTRIBUTORS ``AS IS'' 28236769Sobrien// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 29236769Sobrien// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 30236769Sobrien// ARE DISCLAIMED. IN NO EVENT SHALL INTEL CORPORATION OR CONTRIBUTORS BE 31236769Sobrien// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 32236769Sobrien// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 33236769Sobrien// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 34236769Sobrien// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 35236769Sobrien// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 36236769Sobrien// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF 37236769Sobrien// THE POSSIBILITY OF SUCH DAMAGE. 38236769Sobrien// 39236769Sobrien// 40236769Sobrien 41236769Sobrien// 42236769Sobrien// Module Name: 43236769Sobrien// 44236769Sobrien// setjmp.s 45236769Sobrien// 46236769Sobrien// Abstract: 47236769Sobrien// 48236769Sobrien// Contains an implementation of setjmp and longjmp for the 49236769Sobrien// IA-64 architecture. 50236769Sobrien 51236769Sobrien .file "setjmp.s" 52236769Sobrien 53236769Sobrien#include <machine/asm.h> 54236769Sobrien__FBSDID("$FreeBSD: head/lib/libc/ia64/gen/_setjmp.S 111897 2003-03-05 04:39:24Z marcel $"); 55236769Sobrien 56236769Sobrien#define LOCORE 57236769Sobrien#include <machine/setjmp.h> 58236769Sobrien 59236769Sobrien// int _setjmp(struct jmp_buffer *) 60236769Sobrien// 61236769Sobrien// Setup a non-local goto. 62236769Sobrien// 63236769Sobrien// Description: 64236769Sobrien// 65236769Sobrien// SetJump stores the current register set in the area pointed to 66236769Sobrien// by "save". It returns zero. Subsequent calls to "LongJump" will 67236769Sobrien// restore the registers and return non-zero to the same location. 68236769Sobrien// 69236769Sobrien// On entry, r32 contains the pointer to the jmp_buffer 70236769Sobrien// 71236769Sobrien 72255253SsjgENTRY(_setjmp, 1) 73236769Sobrien add r10 = J_PREDS, r32 // skip Unats & pfs save area 74236769Sobrien add r11 = J_BSP, r32 75236769Sobrien // 76236769Sobrien // save immediate context 77236769Sobrien // 78236769Sobrien mov r2 = ar.bsp // save backing store pointer 79255253Ssjg mov r3 = pr // save predicates 80236769Sobrien flushrs 81236769Sobrien ;; 82236769Sobrien // 83236769Sobrien // save user Unat register 84236769Sobrien // 85236769Sobrien mov r16 = ar.lc // save loop count register 86236769Sobrien mov r14 = ar.unat // save user Unat register 87236769Sobrien 88236769Sobrien st8 [r10] = r3, J_LC-J_PREDS 89236769Sobrien st8 [r11] = r2, J_R4-J_BSP 90236769Sobrien ;; 91236769Sobrien st8 [r10] = r16, J_R5-J_LC 92236769Sobrien st8 [r32] = r14, J_NATS // Note: Unat at the 93236769Sobrien // beginning of the save area 94236769Sobrien mov r15 = ar.pfs 95236769Sobrien ;; 96236769Sobrien // 97236769Sobrien // save preserved general registers & NaT's 98236769Sobrien // 99236769Sobrien .mem.offset 0,0 100236769Sobrien st8.spill [r11] = r4, J_R6-J_R4 101236769Sobrien .mem.offset 8,0 102236769Sobrien st8.spill [r10] = r5, J_R7-J_R5 103236769Sobrien ;; 104236769Sobrien .mem.offset 16,0 105236769Sobrien st8.spill [r11] = r6, J_SP-J_R6 106236769Sobrien .mem.offset 24,0 107236769Sobrien st8.spill [r10] = r7, J_F3-J_R7 108236769Sobrien ;; 109236769Sobrien st8.spill [r11] = sp, J_F2-J_SP 110236769Sobrien mov r16 = ar.rsc 111236769Sobrien ;; 112236769Sobrien // 113236769Sobrien // save spilled Unat and pfs registers 114236769Sobrien // 115236769Sobrien mov r2 = ar.unat // save Unat register after spill 116236769Sobrien mov ar.rsc = r0 117236769Sobrien ;; 118236769Sobrien st8 [r32] = r2, J_PFS-J_NATS // save unat for spilled regs 119236769Sobrien mov r17 = ar.rnat 120236769Sobrien ;; 121236769Sobrien st8 [r32] = r15, J_RNAT-J_PFS // save pfs 122236769Sobrien mov ar.rsc = r16 123236769Sobrien // 124236769Sobrien // save floating registers 125236769Sobrien // 126236769Sobrien stf.spill [r11] = f2, J_F4-J_F2 127236769Sobrien stf.spill [r10] = f3, J_F5-J_F3 128236769Sobrien ;; 129236769Sobrien stf.spill [r11] = f4, J_F16-J_F4 130236769Sobrien stf.spill [r10] = f5, J_F17-J_F5 131236769Sobrien ;; 132236769Sobrien stf.spill [r11] = f16, J_F18-J_F16 133236769Sobrien stf.spill [r10] = f17, J_F19-J_F17 134236769Sobrien ;; 135236769Sobrien stf.spill [r11] = f18, J_F20-J_F18 136236769Sobrien stf.spill [r10] = f19, J_F21-J_F19 137236769Sobrien ;; 138236769Sobrien stf.spill [r11] = f20, J_F22-J_F20 139236769Sobrien stf.spill [r10] = f21, J_F23-J_F21 140236769Sobrien ;; 141236769Sobrien stf.spill [r11] = f22, J_F24-J_F22 142253883Ssjg stf.spill [r10] = f23, J_F25-J_F23 143236769Sobrien ;; 144250164Ssjg stf.spill [r11] = f24, J_F26-J_F24 145250164Ssjg stf.spill [r10] = f25, J_F27-J_F25 146250164Ssjg ;; 147250164Ssjg stf.spill [r11] = f26, J_F28-J_F26 148250164Ssjg stf.spill [r10] = f27, J_F29-J_F27 149250164Ssjg ;; 150250164Ssjg stf.spill [r11] = f28, J_F30-J_F28 151250164Ssjg stf.spill [r10] = f29, J_F31-J_F29 152250164Ssjg ;; 153250164Ssjg stf.spill [r11] = f30, J_FPSR-J_F30 154250164Ssjg stf.spill [r10] = f31, J_B0-J_F31 // size of f31 + fpsr 155236769Sobrien ;; 156236769Sobrien st8 [r32] = r17 157236769Sobrien // 158236769Sobrien // save FPSR register & branch registers 159236769Sobrien // 160236769Sobrien mov r2 = ar.fpsr // save fpsr register 161236769Sobrien mov r3 = b0 162236769Sobrien ;; 163236769Sobrien st8 [r11] = r2, J_B1-J_FPSR 164236769Sobrien st8 [r10] = r3, J_B2-J_B0 165236769Sobrien mov r2 = b1 166236769Sobrien mov r3 = b2 167236769Sobrien ;; 168236769Sobrien st8 [r11] = r2, J_B3-J_B1 169236769Sobrien st8 [r10] = r3, J_B4-J_B2 170236769Sobrien mov r2 = b3 171236769Sobrien mov r3 = b4 172236769Sobrien ;; 173236769Sobrien st8 [r11] = r2, J_B5-J_B3 174236769Sobrien st8 [r10] = r3, J_GP-J_B4 175236769Sobrien mov r2 = b5 176236769Sobrien ;; 177236769Sobrien st8 [r11] = r2 178236769Sobrien st8 [r10] = r1 179236769Sobrien ;; 180236769Sobrien // 181236769Sobrien // return 182236769Sobrien // 183236769Sobrien mov r8 = r0 // return 0 from setjmp 184236769Sobrien mov ar.unat = r14 // restore unat 185236769Sobrien br.ret.sptk b0 186236769Sobrien 187236769SobrienEND(_setjmp) 188236769Sobrien 189236769Sobrien 190255253Ssjg// 191236769Sobrien// void _longjmp(struct jmp_buffer *, int val) 192236769Sobrien// 193236769Sobrien// Perform a non-local goto. 194236769Sobrien// 195236769Sobrien// Description: 196236769Sobrien// 197236769Sobrien// LongJump initializes the register set to the values saved by a 198236769Sobrien// previous 'SetJump' and jumps to the return location saved by that 199236769Sobrien// 'SetJump'. This has the effect of unwinding the stack and returning 200236769Sobrien// for a second time to the 'SetJump'. 201236769Sobrien// 202236769Sobrien 203236769Sobrien WEAK_ALIAS(_longjmp,___longjmp) 204236769SobrienENTRY(___longjmp, 2) 205236769Sobrien mov r14 = ar.rsc // get user RSC conf 206236769Sobrien mov r8 = r33 // return value 207236769Sobrien add r10 = J_PFS, r32 // get address of pfs 208236769Sobrien ;; 209236769Sobrien mov ar.rsc = r0 210236769Sobrien add r11 = J_NATS, r32 211236769Sobrien add r17 = J_RNAT, r32 212236769Sobrien ;; 213236769Sobrien ld8 r15 = [r10], J_BSP-J_PFS // get pfs 214236769Sobrien ld8 r2 = [r11], J_LC-J_NATS // get unat for spilled regs 215236769Sobrien mov r31 = r32 216236769Sobrien ;; 217236769Sobrien loadrs 218236769Sobrien mov ar.unat = r2 219236769Sobrien cmp.eq p6,p0=0,r8 // Return value 0? 220236769Sobrien ;; 221236769Sobrien ld8 r16 = [r10], J_PREDS-J_BSP // get backing store pointer 222236769Sobrien ld8 r17 = [r17] // ar.rnat 223236769Sobrien mov ar.pfs = r15 224236769Sobrien ;; 225236769Sobrien mov ar.bspstore = r16 226236769Sobrien(p6) add r8 = 1, r0 227236769Sobrien ;; 228236769Sobrien mov ar.rnat = r17 229236769Sobrien mov ar.rsc = r14 // restore RSC conf 230236769Sobrien 231236769Sobrien ld8 r3 = [r11], J_R4-J_LC // get lc register 232236769Sobrien ld8 r2 = [r10], J_R5-J_PREDS // get predicates 233236769Sobrien ;; 234236769Sobrien mov pr = r2, -1 235236769Sobrien mov ar.lc = r3 236236769Sobrien // 237236769Sobrien // restore preserved general registers & NaT's 238236769Sobrien // 239236769Sobrien ld8.fill r4 = [r11], J_R6-J_R4 240236769Sobrien ;; 241236769Sobrien ld8.fill r5 = [r10], J_R7-J_R5 242236769Sobrien ld8.fill r6 = [r11], J_SP-J_R6 243236769Sobrien ;; 244236769Sobrien ld8.fill r7 = [r10], J_F2-J_R7 245236769Sobrien ld8.fill sp = [r11], J_F3-J_SP 246236769Sobrien ;; 247236769Sobrien // 248236769Sobrien // restore floating registers 249236769Sobrien // 250236769Sobrien ldf.fill f2 = [r10], J_F4-J_F2 251236769Sobrien ldf.fill f3 = [r11], J_F5-J_F3 252236769Sobrien ;; 253236769Sobrien ldf.fill f4 = [r10], J_F16-J_F4 254236769Sobrien ldf.fill f5 = [r11], J_F17-J_F5 255236769Sobrien ;; 256236769Sobrien ldf.fill f16 = [r10], J_F18-J_F16 257236769Sobrien ldf.fill f17 = [r11], J_F19-J_F17 258236769Sobrien ;; 259236769Sobrien ldf.fill f18 = [r10], J_F20-J_F18 260236769Sobrien ldf.fill f19 = [r11], J_F21-J_F19 261236769Sobrien ;; 262236769Sobrien ldf.fill f20 = [r10], J_F22-J_F20 263236769Sobrien ldf.fill f21 = [r11], J_F23-J_F21 264236769Sobrien ;; 265236769Sobrien ldf.fill f22 = [r10], J_F24-J_F22 266236769Sobrien ldf.fill f23 = [r11], J_F25-J_F23 267236769Sobrien ;; 268236769Sobrien ldf.fill f24 = [r10], J_F26-J_F24 269236769Sobrien ldf.fill f25 = [r11], J_F27-J_F25 270236769Sobrien ;; 271236769Sobrien ldf.fill f26 = [r10], J_F28-J_F26 272236769Sobrien ldf.fill f27 = [r11], J_F29-J_F27 273236769Sobrien ;; 274236769Sobrien ldf.fill f28 = [r10], J_F30-J_F28 275236769Sobrien ldf.fill f29 = [r11], J_F31-J_F29 276236769Sobrien ;; 277236769Sobrien ldf.fill f30 = [r10], J_FPSR-J_F30 278236769Sobrien ldf.fill f31 = [r11], J_B0-J_F31 ;; 279236769Sobrien 280236769Sobrien // 281236769Sobrien // restore branch registers and fpsr 282236769Sobrien // 283236769Sobrien ld8 r16 = [r10], J_B1-J_FPSR // get fpsr 284236769Sobrien ld8 r17 = [r11], J_B2-J_B0 // get return pointer 285236769Sobrien ;; 286236769Sobrien mov ar.fpsr = r16 287236769Sobrien mov b0 = r17 288236769Sobrien ld8 r2 = [r10], J_B3-J_B1 289236769Sobrien ld8 r3 = [r11], J_B4-J_B2 290236769Sobrien ;; 291236769Sobrien mov b1 = r2 292236769Sobrien mov b2 = r3 293236769Sobrien ld8 r2 = [r10], J_B5-J_B3 294236769Sobrien ld8 r3 = [r11], J_GP-J_B4 295236769Sobrien ;; 296236769Sobrien mov b3 = r2 297236769Sobrien mov b4 = r3 298236769Sobrien ld8 r2 = [r10] 299236769Sobrien ld8 r1 = [r11] 300236769Sobrien ld8 r21 = [r31] // get user unat 301236769Sobrien ;; 302236769Sobrien mov b5 = r2 303236769Sobrien mov ar.unat = r21 304236769Sobrien 305236769Sobrien // 306236769Sobrien // invalidate ALAT 307236769Sobrien // 308236769Sobrien invala ;; 309236769Sobrien 310236769Sobrien br.ret.sptk b0 311236769Sobrien 312236769SobrienEND(___longjmp) 313236769Sobrien