]>
Commit | Line | Data |
---|---|---|
878ddf1f | 1 | //++\r |
2 | // Copyright (c) 2004, Intel Corporation \r | |
3 | // All rights reserved. This program and the accompanying materials \r | |
4 | // are licensed and made available under the terms and conditions of the BSD License \r | |
5 | // which accompanies this distribution. The full text of the license may be found at \r | |
6 | // http://opensource.org/licenses/bsd-license.php \r | |
7 | // \r | |
8 | // THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, \r | |
9 | // WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. \r | |
10 | // \r | |
11 | // Module Name:\r | |
12 | //\r | |
13 | // setjmp.s\r | |
14 | //\r | |
15 | // Abstract:\r | |
16 | //\r | |
17 | // Contains an implementation of setjmp and longjmp for the\r | |
18 | // Itanium-based architecture.\r | |
19 | //\r | |
20 | //\r | |
21 | //\r | |
22 | // Revision History:\r | |
23 | //\r | |
24 | //--\r | |
25 | \r | |
26 | .file "setjmp.s"\r | |
27 | \r | |
28 | #include <asm.h>\r | |
29 | #include <ia_64gen.h>\r | |
30 | \r | |
31 | // int SetJump(struct jmp_buffer save)\r | |
32 | //\r | |
33 | // Setup a non-local goto.\r | |
34 | //\r | |
35 | // Description:\r | |
36 | //\r | |
37 | // SetJump stores the current register set in the area pointed to\r | |
38 | // by "save". It returns zero. Subsequent calls to "LongJump" will\r | |
39 | // restore the registers and return non-zero to the same location.\r | |
40 | //\r | |
41 | // On entry, r32 contains the pointer to the jmp_buffer\r | |
42 | //\r | |
43 | \r | |
44 | PROCEDURE_ENTRY(SetJump)\r | |
45 | //\r | |
46 | // Make sure buffer is aligned at 16byte boundary\r | |
47 | //\r | |
48 | mov r32 = r33 \r | |
49 | \r | |
50 | add r10 = -0x10,r0 ;; // mask the lower 4 bits\r | |
51 | and r32 = r32, r10;; \r | |
52 | add r32 = 0x10, r32;; // move to next 16 byte boundary\r | |
53 | \r | |
54 | add r10 = J_PREDS, r32 // skip Unats & pfs save area\r | |
55 | add r11 = J_BSP, r32\r | |
56 | //\r | |
57 | // save immediate context\r | |
58 | //\r | |
59 | mov r2 = ar.bsp // save backing store pointer\r | |
60 | mov r3 = pr // save predicates\r | |
61 | ;;\r | |
62 | //\r | |
63 | // save user Unat register\r | |
64 | //\r | |
65 | mov r16 = ar.lc // save loop count register\r | |
66 | mov r14 = ar.unat // save user Unat register\r | |
67 | \r | |
68 | st8 [r10] = r3, J_LC-J_PREDS\r | |
69 | st8 [r11] = r2, J_R4-J_BSP\r | |
70 | ;;\r | |
71 | st8 [r10] = r16, J_R5-J_LC\r | |
72 | st8 [r32] = r14, J_NATS // Note: Unat at the \r | |
73 | // beginning of the save area\r | |
74 | mov r15 = ar.pfs\r | |
75 | ;;\r | |
76 | //\r | |
77 | // save preserved general registers & NaT's\r | |
78 | //\r | |
79 | st8.spill [r11] = r4, J_R6-J_R4\r | |
80 | ;;\r | |
81 | st8.spill [r10] = r5, J_R7-J_R5 \r | |
82 | ;;\r | |
83 | st8.spill [r11] = r6, J_SP-J_R6\r | |
84 | ;;\r | |
85 | st8.spill [r10] = r7, J_F3-J_R7 \r | |
86 | ;;\r | |
87 | st8.spill [r11] = sp, J_F2-J_SP\r | |
88 | ;;\r | |
89 | //\r | |
90 | // save spilled Unat and pfs registers\r | |
91 | //\r | |
92 | mov r2 = ar.unat // save Unat register after spill\r | |
93 | ;;\r | |
94 | st8 [r32] = r2, J_PFS-J_NATS // save unat for spilled regs\r | |
95 | ;;\r | |
96 | st8 [r32] = r15 // save pfs\r | |
97 | //\r | |
98 | // save floating registers \r | |
99 | //\r | |
100 | stf.spill [r11] = f2, J_F4-J_F2\r | |
101 | stf.spill [r10] = f3, J_F5-J_F3 \r | |
102 | ;;\r | |
103 | stf.spill [r11] = f4, J_F16-J_F4\r | |
104 | stf.spill [r10] = f5, J_F17-J_F5 \r | |
105 | ;;\r | |
106 | stf.spill [r11] = f16, J_F18-J_F16\r | |
107 | stf.spill [r10] = f17, J_F19-J_F17 \r | |
108 | ;;\r | |
109 | stf.spill [r11] = f18, J_F20-J_F18\r | |
110 | stf.spill [r10] = f19, J_F21-J_F19 \r | |
111 | ;;\r | |
112 | stf.spill [r11] = f20, J_F22-J_F20\r | |
113 | stf.spill [r10] = f21, J_F23-J_F21 \r | |
114 | ;;\r | |
115 | stf.spill [r11] = f22, J_F24-J_F22\r | |
116 | stf.spill [r10] = f23, J_F25-J_F23 \r | |
117 | ;;\r | |
118 | stf.spill [r11] = f24, J_F26-J_F24\r | |
119 | stf.spill [r10] = f25, J_F27-J_F25 \r | |
120 | ;;\r | |
121 | stf.spill [r11] = f26, J_F28-J_F26\r | |
122 | stf.spill [r10] = f27, J_F29-J_F27 \r | |
123 | ;;\r | |
124 | stf.spill [r11] = f28, J_F30-J_F28\r | |
125 | stf.spill [r10] = f29, J_F31-J_F29 \r | |
126 | ;;\r | |
127 | stf.spill [r11] = f30, J_FPSR-J_F30\r | |
128 | stf.spill [r10] = f31, J_B0-J_F31 // size of f31 + fpsr\r | |
129 | //\r | |
130 | // save FPSR register & branch registers\r | |
131 | //\r | |
132 | mov r2 = ar.fpsr // save fpsr register\r | |
133 | mov r3 = b0 \r | |
134 | ;;\r | |
135 | st8 [r11] = r2, J_B1-J_FPSR\r | |
136 | st8 [r10] = r3, J_B2-J_B0\r | |
137 | mov r2 = b1\r | |
138 | mov r3 = b2 \r | |
139 | ;;\r | |
140 | st8 [r11] = r2, J_B3-J_B1\r | |
141 | st8 [r10] = r3, J_B4-J_B2\r | |
142 | mov r2 = b3\r | |
143 | mov r3 = b4 \r | |
144 | ;;\r | |
145 | st8 [r11] = r2, J_B5-J_B3\r | |
146 | st8 [r10] = r3\r | |
147 | mov r2 = b5 \r | |
148 | ;;\r | |
149 | st8 [r11] = r2\r | |
150 | ;;\r | |
151 | //\r | |
152 | // return\r | |
153 | //\r | |
154 | mov r8 = r0 // return 0 from setjmp\r | |
155 | mov ar.unat = r14 // restore unat\r | |
156 | br.ret.sptk b0\r | |
157 | \r | |
158 | PROCEDURE_EXIT(SetJump)\r | |
159 | \r | |
160 | \r | |
161 | //\r | |
162 | // void LongJump(struct jmp_buffer *)\r | |
163 | //\r | |
164 | // Perform a non-local goto.\r | |
165 | //\r | |
166 | // Description:\r | |
167 | //\r | |
168 | // LongJump initializes the register set to the values saved by a\r | |
169 | // previous 'SetJump' and jumps to the return location saved by that\r | |
170 | // 'SetJump'. This has the effect of unwinding the stack and returning\r | |
171 | // for a second time to the 'SetJump'.\r | |
172 | //\r | |
173 | \r | |
174 | PROCEDURE_ENTRY(LongJump)\r | |
175 | //\r | |
176 | // Make sure buffer is aligned at 16byte boundary\r | |
177 | //\r | |
178 | mov r32 = r33 \r | |
179 | \r | |
180 | add r10 = -0x10,r0 ;; // mask the lower 4 bits\r | |
181 | and r32 = r32, r10;; \r | |
182 | add r32 = 0x10, r32;; // move to next 16 byte boundary\r | |
183 | \r | |
184 | //\r | |
185 | // caching the return value as we do invala in the end\r | |
186 | //\r | |
187 | /// mov r8 = r33 // return value\r | |
188 | mov r8 = 1 // For now return hard coded 1\r | |
189 | \r | |
190 | //\r | |
191 | // get immediate context\r | |
192 | //\r | |
193 | mov r14 = ar.rsc // get user RSC conf \r | |
194 | add r10 = J_PFS, r32 // get address of pfs\r | |
195 | add r11 = J_NATS, r32\r | |
196 | ;;\r | |
197 | ld8 r15 = [r10], J_BSP-J_PFS // get pfs\r | |
198 | ld8 r2 = [r11], J_LC-J_NATS // get unat for spilled regs\r | |
199 | ;;\r | |
200 | mov ar.unat = r2\r | |
201 | ;;\r | |
202 | ld8 r16 = [r10], J_PREDS-J_BSP // get backing store pointer\r | |
203 | mov ar.rsc = r0 // put RSE in enforced lazy \r | |
204 | mov ar.pfs = r15\r | |
205 | ;;\r | |
206 | \r | |
207 | //\r | |
208 | // while returning from longjmp the BSPSTORE and BSP needs to be\r | |
209 | // same and discard all the registers allocated after we did\r | |
210 | // setjmp. Also, we need to generate the RNAT register since we\r | |
211 | // did not flushed the RSE on setjmp.\r | |
212 | //\r | |
213 | mov r17 = ar.bspstore // get current BSPSTORE\r | |
214 | ;;\r | |
215 | cmp.ltu p6,p7 = r17, r16 // is it less than BSP of \r | |
216 | (p6) br.spnt.few .flush_rse\r | |
217 | mov r19 = ar.rnat // get current RNAT\r | |
218 | ;;\r | |
219 | loadrs // invalidate dirty regs\r | |
220 | br.sptk.many .restore_rnat // restore RNAT\r | |
221 | \r | |
222 | .flush_rse:\r | |
223 | flushrs\r | |
224 | ;;\r | |
225 | mov r19 = ar.rnat // get current RNAT\r | |
226 | mov r17 = r16 // current BSPSTORE\r | |
227 | ;;\r | |
228 | .restore_rnat:\r | |
229 | //\r | |
230 | // check if RNAT is saved between saved BSP and curr BSPSTORE\r | |
231 | //\r | |
232 | dep r18 = 1,r16,3,6 // get RNAT address\r | |
233 | ;;\r | |
234 | cmp.ltu p8,p9 = r18, r17 // RNAT saved on RSE\r | |
235 | ;;\r | |
236 | (p8) ld8 r19 = [r18] // get RNAT from RSE\r | |
237 | ;;\r | |
238 | mov ar.bspstore = r16 // set new BSPSTORE \r | |
239 | ;;\r | |
240 | mov ar.rnat = r19 // restore RNAT\r | |
241 | mov ar.rsc = r14 // restore RSC conf\r | |
242 | \r | |
243 | \r | |
244 | ld8 r3 = [r11], J_R4-J_LC // get lc register\r | |
245 | ld8 r2 = [r10], J_R5-J_PREDS // get predicates\r | |
246 | ;;\r | |
247 | mov pr = r2, -1\r | |
248 | mov ar.lc = r3\r | |
249 | //\r | |
250 | // restore preserved general registers & NaT's\r | |
251 | //\r | |
252 | ld8.fill r4 = [r11], J_R6-J_R4\r | |
253 | ;;\r | |
254 | ld8.fill r5 = [r10], J_R7-J_R5 \r | |
255 | ld8.fill r6 = [r11], J_SP-J_R6\r | |
256 | ;;\r | |
257 | ld8.fill r7 = [r10], J_F2-J_R7\r | |
258 | ld8.fill sp = [r11], J_F3-J_SP\r | |
259 | ;;\r | |
260 | //\r | |
261 | // restore floating registers \r | |
262 | //\r | |
263 | ldf.fill f2 = [r10], J_F4-J_F2\r | |
264 | ldf.fill f3 = [r11], J_F5-J_F3 \r | |
265 | ;;\r | |
266 | ldf.fill f4 = [r10], J_F16-J_F4\r | |
267 | ldf.fill f5 = [r11], J_F17-J_F5 \r | |
268 | ;;\r | |
269 | ldf.fill f16 = [r10], J_F18-J_F16\r | |
270 | ldf.fill f17 = [r11], J_F19-J_F17\r | |
271 | ;;\r | |
272 | ldf.fill f18 = [r10], J_F20-J_F18\r | |
273 | ldf.fill f19 = [r11], J_F21-J_F19\r | |
274 | ;;\r | |
275 | ldf.fill f20 = [r10], J_F22-J_F20\r | |
276 | ldf.fill f21 = [r11], J_F23-J_F21\r | |
277 | ;;\r | |
278 | ldf.fill f22 = [r10], J_F24-J_F22\r | |
279 | ldf.fill f23 = [r11], J_F25-J_F23 \r | |
280 | ;;\r | |
281 | ldf.fill f24 = [r10], J_F26-J_F24\r | |
282 | ldf.fill f25 = [r11], J_F27-J_F25\r | |
283 | ;;\r | |
284 | ldf.fill f26 = [r10], J_F28-J_F26\r | |
285 | ldf.fill f27 = [r11], J_F29-J_F27\r | |
286 | ;;\r | |
287 | ldf.fill f28 = [r10], J_F30-J_F28\r | |
288 | ldf.fill f29 = [r11], J_F31-J_F29 \r | |
289 | ;;\r | |
290 | ldf.fill f30 = [r10], J_FPSR-J_F30\r | |
291 | ldf.fill f31 = [r11], J_B0-J_F31 ;;\r | |
292 | \r | |
293 | //\r | |
294 | // restore branch registers and fpsr\r | |
295 | //\r | |
296 | ld8 r16 = [r10], J_B1-J_FPSR // get fpsr\r | |
297 | ld8 r17 = [r11], J_B2-J_B0 // get return pointer\r | |
298 | ;;\r | |
299 | mov ar.fpsr = r16\r | |
300 | mov b0 = r17\r | |
301 | ld8 r2 = [r10], J_B3-J_B1\r | |
302 | ld8 r3 = [r11], J_B4-J_B2\r | |
303 | ;;\r | |
304 | mov b1 = r2\r | |
305 | mov b2 = r3\r | |
306 | ld8 r2 = [r10], J_B5-J_B3\r | |
307 | ld8 r3 = [r11]\r | |
308 | ;;\r | |
309 | mov b3 = r2\r | |
310 | mov b4 = r3 \r | |
311 | ld8 r2 = [r10]\r | |
312 | ld8 r21 = [r32] // get user unat\r | |
313 | ;;\r | |
314 | mov b5 = r2\r | |
315 | mov ar.unat = r21\r | |
316 | \r | |
317 | //\r | |
318 | // invalidate ALAT\r | |
319 | //\r | |
320 | invala ;;\r | |
321 | \r | |
322 | br.ret.sptk b0\r | |
323 | PROCEDURE_EXIT(LongJump)\r | |
324 | \r | |
325 | \r |