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
149
150
151
152
153
154
155
156
|
// TITLE("Set Jump Extended")
//++
//
// Copyright (c) 1993 Microsoft Corporation
//
// Module Name:
//
// setjmpex.s
//
// Abstract:
//
// This module implements the MIPS specific routine to provide SAFE
// handling of setjmp/longjmp with respect to structured exception
// handling.
//
// Author:
//
// David N. Cutler (davec) 2-Apr-1993
//
// Environment:
//
// Any mode.
//
// Revision History:
//
//--
#include "ksmips.h"
//
// Define variable that will cause setjmp/longjmp to be safe with respect
// to structured exception handling.
//
.globl _setjmpexused
.data
_setjmpexused:
.word _setjmpex // set address of safe setjmp routine
SBTTL("Set Jump Extended")
//++
//
// int
// _setjmpex (
// IN jmp_buf JumpBuffer
// )
//
// Routine Description:
//
// This function transfers control to the actual setjmp routine.
//
// Arguments:
//
// JumpBuffer (a0) - Supplies the address of a jump buffer to store the
// jump information.
//
// Return Value:
//
// A value of zero is returned.
//
//--
.struct 0
.space 4 * 4 // argument save area
SjS0: .space 4 // saved integer register s0
SjFl: .space 4 // in function flag variable
.space 4 // fill
SjRa: .space 4 // saved return address
SetjmpFrameLength:
NESTED_ENTRY(_setjmpex, SetjmpFrameLength, zero)
subu sp,sp,SetjmpFrameLength // allocate stack frame
sw s0,SjS0(sp) // save integer register s0
sw ra,SjRa(sp) // save return address
move s0,sp // set frame pointer
PROLOGUE_END
subu sp,sp,ContextFrameLength + 16 // allocate a context frame
//
// Save the nonvolatile machine state in both the jump buffer and a context
// record that will be used to compute the virtual frame pointer.
//
sdc1 f20,JbFltF20(a0) // save floating registers f20 - f31
sdc1 f22,JbFltF22(a0) //
sdc1 f24,JbFltF24(a0) //
sdc1 f26,JbFltF26(a0) //
sdc1 f28,JbFltF28(a0) //
sdc1 f30,JbFltF30(a0) //
lw v0,SjS0(s0) // get saved integer register s0
sw v0,JbIntS0(a0) // save integer registers s0 - s8
sw s1,JbIntS1(a0) //
sw s2,JbIntS2(a0) //
sw s3,JbIntS3(a0) //
sw s4,JbIntS4(a0) //
sw s5,JbIntS5(a0) //
sw s6,JbIntS6(a0) //
sw s7,JbIntS7(a0) //
sw s8,JbIntS8(a0) //
sw ra,JbFir(a0) // get setjmp return address
addu v0,s0,SetjmpFrameLength // compute stack pointer address
sw v0,JbIntSp(a0) // save stack pointer
sdc1 f20,CxFltF20 + 16(sp) // save floating registers f20 - f31
sdc1 f22,CxFltF22 + 16(sp) //
sdc1 f24,CxFltF24 + 16(sp) //
sdc1 f26,CxFltF26 + 16(sp) //
sdc1 f28,CxFltF28 + 16(sp) //
sdc1 f30,CxFltF30 + 16(sp) //
lw v0,SjS0(s0) // get saved integer register s0
sw v0,CxIntS0 + 16(sp) // save integer registers s0 - s8
sw s1,CxIntS1 + 16(sp) //
sw s2,CxIntS2 + 16(sp) //
sw s3,CxIntS3 + 16(sp) //
sw s4,CxIntS4 + 16(sp) //
sw s5,CxIntS5 + 16(sp) //
sw s6,CxIntS6 + 16(sp) //
sw s7,CxIntS7 + 16(sp) //
sw s8,CxIntS8 + 16(sp) // save integer register s8
sw gp,CxIntGp + 16(sp) // save integer register gp
addu v0,s0,SetjmpFrameLength // compute stack pointer address
sw v0,CxIntSp + 16(sp) // save stack pointer
sw ra,CxIntRa + 16(sp) // save return address
sw ra,CxFir + 16(sp) // save return address
//
// Perform unwind to determine the virtual frame pointer of the caller.
//
addu a0,a0,JbType // set virtual frame address argument
sw a0,4 * 4(sp) //
subu a0,ra,4 // compute control PC address
jal RtlLookupFunctionEntry // lookup function table address
lw a0,SjRa(s0) // get return address
subu a0,a0,4 // compute control PC address
move a1,v0 // set address of function entry
addu a2,sp,16 // compute address of context record
addu a3,s0,SjFl // set address of in function variable
sw zero,4 * 5(sp) // set context pointer array address
jal RtlVirtualUnwind // compute virtual frame pointer value
//
// Set return value, restore registers, deallocate stack frame, and return.
//
move v0,zero // set return value
move sp,s0 // reset stack pointer
lw s0,SjS0(sp) // restore integer register s0
lw ra,SjRa(sp) // restore return address
addu sp,sp,SetjmpFrameLength // deallocate stack frame
j ra // return
.end _setjmpex
|