1/* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22/* 23 * Copyright 2004 Sun Microsystems, Inc. All rights reserved. 24 * Use is subject to license terms. 25 */ 26 27#ident "%Z%%M% %I% %E% SMI" 28 29#if defined(lint) 30 31typedef long *jmp_buf_ptr; 32 33#else /* lint */ 34 35#include <sys/asm_linkage.h> 36 37#endif /* lint */ 38 39/* 40 * _setjmp(buf_ptr) 41 * buf_ptr points to a five word array (jmp_buf). In the first is our 42 * return address, the second, is the callers SP. 43 * The rest is cleared by _setjmp 44 * 45 * +----------------+ 46 * %i0-> | pc | 47 * +----------------+ 48 * | sp | 49 * +----------------+ 50 * | sigmask | 51 * +----------------+ 52 * | stagstack | 53 * | structure | 54 * +----------------+ 55 */ 56 57#if defined(lint) 58 59/* ARGSUSED */ 60int 61_setjmp(jmp_buf_ptr buf_ptr) 62{ return (0); } 63 64#else /* lint */ 65 66 PCVAL = 0 ! offsets in buf structure 67 SPVAL = 4 68 SIGMASK = 8 69 SIGSTACK = 12 70 71 SS_SP = 0 ! offset in sigstack structure 72 SS_ONSTACK = 4 73 74 ENTRY(_setjmp) 75 st %o7, [%o0 + PCVAL] ! return pc 76 st %sp, [%o0 + SPVAL] ! save caller's sp 77 clr [%o0 + SIGMASK] ! clear the remainder of the jmp_buf 78 clr [%o0 + SIGSTACK + SS_SP] 79 clr [%o0 + SIGSTACK + SS_ONSTACK] 80 retl 81 clr %o0 82 SET_SIZE(_setjmp) 83 84#endif /* lint */ 85 86/* 87 * _longjmp(buf_ptr, val) 88 * buf_ptr points to an array which has been initialized by _setjmp. 89 * val is the value we wish to return to _setjmp's caller 90 * 91 * We will flush our registers by doing (nwindows-1) save instructions. 92 * This could be better done as a kernel call. This is necessary to 93 * ensure that the registers we want to pick up are stored in the stack. 94 * Then, we set fp from the saved fp and make ourselves a stack frame. 95 */ 96 97#if defined(lint) 98 99/* ARGSUSED */ 100void 101_longjmp(jmp_buf_ptr buf_ptr, int val) 102{ 103 return; 104} 105 106#else /* lint */ 107 108 ENTRY(_longjmp) 109 save %sp, -WINDOWSIZE, %sp 110 ! 111 ! flush all register windows to the stack. 112 ! 113 set nwindows, %g7 114 ld [%g7], %g7 115 sub %g7, 2, %g6 1161: 117 deccc %g6 ! all windows done? 118 bnz 1b 119 save %sp, -WINDOWSIZE, %sp 120 sub %g7, 2, %g6 1212: 122 deccc %g6 ! all windows done? 123 bnz 2b 124 restore ! delay slot, increment CWP 125 126 ld [%i0 + SPVAL], %fp ! build new stack frame 127 sub %fp, -SA(MINFRAME), %sp ! establish new save area 128 ld [%i0 + PCVAL], %i7 ! get new return pc 129 ret 130 restore %i1, 0, %o0 ! return (val) 131 SET_SIZE(_longjmp) 132 133#endif /* lint */ 134