1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
|
// TITLE("Set Jump")
//++
//
// Copyright (c) 1993 Microsoft Corporation
// Copyright (c) 1993 Digital Equipment Corporation
//
// Module Name:
//
// setjmp.s
//
// Abstract:
//
// This module implements the Alpha acc compiler specific routine to
// provide SAFE handling of setjmp/longjmp with respect to structured
// exception handling.
//
// N.B. This function has been replaced by setjmp/setjmpex/longjmp in the
// C runtime library. It remains here for backwards compatibility of
// Beta 2 applications expecting setjmp and longjmp to be present in
// ntdll, or for new acc compiled applications that link with ntdll
// before libc.
//
// Author:
//
// David N. Cutler (davec) 2-Apr-1993
//
// Environment:
//
// Any mode.
//
// Revision History:
//
// Thomas Van Baak (tvb) 22-Apr-1993
//
// Adapted for Alpha AXP.
//
//--
#include "ksalpha.h"
SBTTL("Set Jump")
//++
//
// int
// setjmp (
// IN jmp_buf JumpBuffer
// )
//
// Routine Description:
//
// This function implements a safe setjmp.
//
// Arguments:
//
// JumpBuffer (a0) - Supplies the address of a jump buffer to store the
// jump information.
//
// N.B. This is an array of double's to force quadword alignment.
//
// Return Value:
//
// A value of zero is returned.
//
//--
.struct 0
SjRa: .space 8 // saved return address
SjS0: .space 8 // saved integer register s0
SjFl: .space 8 // InFunction flag variable
SjEf: .space 8 // EstablisherFrame(s) structure
SjCx: .space ContextFrameLength // context frame
SetjmpFrameLength:
NESTED_ENTRY(setjmp, SetjmpFrameLength, zero)
lda sp, -SetjmpFrameLength(sp) // allocate stack frame
stq ra, SjRa(sp) // save return address
stq s0, SjS0(sp) // save integer register s0
PROLOGUE_END
//
// Save the nonvolatile machine state.
//
lda t0, SjCx(sp) // address of context record
.set noreorder
.set noat
stt f2, CxFltF2(t0) // save floating registers f2 - f9
stt f3, CxFltF3(t0) //
stt f4, CxFltF4(t0) //
stt f5, CxFltF5(t0) //
stt f6, CxFltF6(t0) //
stt f7, CxFltF7(t0) //
stt f8, CxFltF8(t0) //
stt f9, CxFltF9(t0) //
stq s0, CxIntS0(t0) // save integer registers s0 - fp/s6
stq s1, CxIntS1(t0) //
stq s2, CxIntS2(t0) //
stq s3, CxIntS3(t0) //
stq s4, CxIntS4(t0) //
stq s5, CxIntS5(t0) //
stq fp, CxIntFp(t0) //
.set at
.set reorder
stq gp, CxIntGp(t0) // save integer register gp
lda v0, SetjmpFrameLength(sp) // compute stack pointer of caller
stq v0, CxIntSp(t0) // save caller stack pointer
stq ra, CxIntRa(t0) // save return address
stq ra, CxFir(t0) // save continuation address
ldil t1, 2 // get acc safe setjmp flag
stl t1, JbType(a0) // set jump buffer context type
stl ra, JbPc(a0) // save target instruction address
mov a0, s0 // preserve jump buffer address
//
// Perform unwind to determine the virtual frame pointer of the caller.
//
subl ra, 4, a0 // compute control PC address
bsr RtlLookupFunctionEntry // lookup function table address
ldq a0, SjRa(sp) // get return address
subl a0, 4, a0 // compute control PC address
mov v0, a1 // set address of function entry
lda a2, SjCx(sp) // address of context record
lda a3, SjFl(sp) // set address of in function variable
lda a4, SjEf(sp) // set frame pointers address
mov zero, a5 // set context pointer array address
bsr RtlVirtualUnwind // compute virtual frame pointer value
//
// Set return value, restore registers, deallocate stack frame, and return.
//
ldl t0, SjEf(sp) // get virtual frame pointer
stl t0, JbFp(s0) // save virtual frame pointer address
mov zero, v0 // set return value
ldq s0, SjS0(sp) // restore integer register s0
ldq ra, SjRa(sp) // restore return address
lda sp, SetjmpFrameLength(sp) // deallocate stack frame
ret zero, (ra) // return
.end setjmp
|