source: mainline/kernel/arch/ia64/src/context.S

Last change on this file was 7cd7a8d, checked in by Jakub Jermar <jakub@…>, 7 years ago

Preserve AR.FPSR in thread context

AR.FPSR is a preserved register so it should be part of the thread
context, leaving its extra copy in istate_t rather for debugging
purposes.

In this commit we also disable all IEEE FP traps and the
Denormal/Unnormal Operand Floating-Point Exception fault for each new
thread context, leaving the thread with the possibility to change this
setting later in uspace.

  • Property mode set to 100644
File size: 8.8 KB
Line 
1#
2# Copyright (c) 2005 Jakub Jermar
3# All rights reserved.
4#
5# Redistribution and use in source and binary forms, with or without
6# modification, are permitted provided that the following conditions
7# are met:
8#
9# - Redistributions of source code must retain the above copyright
10# notice, this list of conditions and the following disclaimer.
11# - Redistributions in binary form must reproduce the above copyright
12# notice, this list of conditions and the following disclaimer in the
13# documentation and/or other materials provided with the distribution.
14# - The name of the author may not be used to endorse or promote products
15# derived from this software without specific prior written permission.
16#
17# THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18# IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19# OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20# IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22# NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26# THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27#
28
29#include <abi/asmtool.h>
30#include <arch/context_struct.h>
31
32.text
33
34FUNCTION_BEGIN(context_save_arch)
35 alloc loc0 = ar.pfs, 1, 50, 0, 0
36 mov loc1 = ar.unat ;;
37 mov loc3 = ar.rsc
38
39 .auto
40
41 /*
42 * Flush dirty registers to backing store.
43 * After this ar.bsp and ar.bspstore are equal.
44 */
45 flushrs
46 mov loc4 = ar.bsp
47
48 /*
49 * Put RSE to enforced lazy mode.
50 * So that ar.rnat can be read.
51 */
52 and loc5 = ~3, loc3
53 mov ar.rsc = loc5
54 mov loc5 = ar.rnat
55
56 .explicit
57
58 mov loc6 = ar.lc
59 mov loc7 = ar.fpsr
60
61 add loc8 = CONTEXT_OFFSET_AR_PFS, in0
62 add loc9 = CONTEXT_OFFSET_AR_UNAT_CALLER, in0
63 add loc10 = CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
64 add loc11 = CONTEXT_OFFSET_AR_RSC, in0
65 add loc12 = CONTEXT_OFFSET_BSP, in0
66 add loc13 = CONTEXT_OFFSET_AR_RNAT, in0
67 add loc14 = CONTEXT_OFFSET_AR_LC, in0
68 add loc15 = CONTEXT_OFFSET_AR_FPSR, in0
69
70 add loc16 = CONTEXT_OFFSET_R1, in0
71 add loc17 = CONTEXT_OFFSET_R4, in0
72 add loc18 = CONTEXT_OFFSET_R5, in0
73 add loc19 = CONTEXT_OFFSET_R6, in0
74 add loc20 = CONTEXT_OFFSET_R7, in0
75 add loc21 = CONTEXT_OFFSET_SP, in0
76 add loc22 = CONTEXT_OFFSET_R13, in0
77
78 add loc23 = CONTEXT_OFFSET_PC, in0
79 add loc24 = CONTEXT_OFFSET_B1, in0
80 add loc25 = CONTEXT_OFFSET_B2, in0
81 add loc26 = CONTEXT_OFFSET_B3, in0
82 add loc27 = CONTEXT_OFFSET_B4, in0
83 add loc28 = CONTEXT_OFFSET_B5, in0
84
85 add loc29 = CONTEXT_OFFSET_PR, in0
86
87 add loc30 = CONTEXT_OFFSET_F2, in0
88 add loc31 = CONTEXT_OFFSET_F3, in0
89 add loc32 = CONTEXT_OFFSET_F4, in0
90 add loc33 = CONTEXT_OFFSET_F5, in0
91
92 add loc34 = CONTEXT_OFFSET_F16, in0
93 add loc35 = CONTEXT_OFFSET_F17, in0
94 add loc36 = CONTEXT_OFFSET_F18, in0
95 add loc37 = CONTEXT_OFFSET_F19, in0
96 add loc38 = CONTEXT_OFFSET_F20, in0
97 add loc39 = CONTEXT_OFFSET_F21, in0
98 add loc40 = CONTEXT_OFFSET_F22, in0
99 add loc41 = CONTEXT_OFFSET_F23, in0
100 add loc42 = CONTEXT_OFFSET_F24, in0
101 add loc43 = CONTEXT_OFFSET_F25, in0
102 add loc44 = CONTEXT_OFFSET_F26, in0
103 add loc45 = CONTEXT_OFFSET_F27, in0
104 add loc46 = CONTEXT_OFFSET_F28, in0
105 add loc47 = CONTEXT_OFFSET_F29, in0
106 add loc48 = CONTEXT_OFFSET_F30, in0
107 add loc49 = CONTEXT_OFFSET_F31, in0 ;;
108
109 /*
110 * Save general registers including NaT bits
111 */
112 st8.spill [loc16] = r1 ;;
113 st8.spill [loc17] = r4 ;;
114 st8.spill [loc18] = r5 ;;
115 st8.spill [loc19] = r6 ;;
116 st8.spill [loc20] = r7 ;;
117 st8.spill [loc21] = r12 ;; /* save sp */
118 st8.spill [loc22] = r13 ;;
119
120 mov loc2 = ar.unat
121
122 /*
123 * Save application registers
124 */
125 st8 [loc8] = loc0 /* save ar.pfs */
126 st8 [loc9] = loc1 ;; /* save ar.unat (caller) */
127 st8 [loc10] = loc2 /* save ar.unat (callee) */
128 st8 [loc11] = loc3 /* save ar.rsc */
129 st8 [loc12] = loc4 /* save ar.bsp */
130 st8 [loc13] = loc5 /* save ar.rnat */
131 st8 [loc14] = loc6 /* save ar.lc */
132 st8 [loc15] = loc7 ;; /* save ar.fpsr */
133
134 /*
135 * Save branch registers
136 */
137 mov loc2 = b0
138 mov loc3 = b1
139 mov loc4 = b2
140 mov loc5 = b3
141 mov loc6 = b4
142 mov loc7 = b5 ;;
143 st8 [loc23] = loc2 /* save pc */
144 st8 [loc24] = loc3
145 st8 [loc25] = loc4
146 st8 [loc26] = loc5
147 st8 [loc27] = loc6
148 st8 [loc28] = loc7 ;;
149
150 /*
151 * Save predicate registers
152 */
153 mov loc2 = pr ;;
154 st8 [loc29] = loc2
155
156 /*
157 * Save floating-point registers.
158 */
159 stf.spill [loc30] = f2
160 stf.spill [loc31] = f3
161 stf.spill [loc32] = f4
162 stf.spill [loc33] = f5
163
164 stf.spill [loc34] = f16
165 stf.spill [loc35] = f17
166 stf.spill [loc36] = f18
167 stf.spill [loc37] = f19
168 stf.spill [loc38] = f20
169 stf.spill [loc39] = f21
170 stf.spill [loc40] = f22
171 stf.spill [loc41] = f23
172 stf.spill [loc42] = f24
173 stf.spill [loc43] = f25
174 stf.spill [loc44] = f26
175 stf.spill [loc45] = f27
176 stf.spill [loc46] = f28
177 stf.spill [loc47] = f29
178 stf.spill [loc48] = f30
179 stf.spill [loc49] = f31
180
181 mov ar.unat = loc1
182
183 add r8 = r0, r0, 1 /* context_save returns 1 */
184 br.ret.sptk.many b0
185FUNCTION_END(context_save_arch)
186
187FUNCTION_BEGIN(context_restore_arch)
188 alloc loc0 = ar.pfs, 1, 51, 0, 0 ;;
189
190 add loc9 = CONTEXT_OFFSET_AR_PFS, in0
191 add loc10 = CONTEXT_OFFSET_AR_UNAT_CALLER, in0
192 add loc11 = CONTEXT_OFFSET_AR_UNAT_CALLEE, in0
193 add loc12 = CONTEXT_OFFSET_AR_RSC, in0
194 add loc13 = CONTEXT_OFFSET_BSP, in0
195 add loc14 = CONTEXT_OFFSET_AR_RNAT, in0
196 add loc15 = CONTEXT_OFFSET_AR_LC, in0
197 add loc16 = CONTEXT_OFFSET_AR_FPSR, in0
198
199 add loc17 = CONTEXT_OFFSET_R1, in0
200 add loc18 = CONTEXT_OFFSET_R4, in0
201 add loc19 = CONTEXT_OFFSET_R5, in0
202 add loc20 = CONTEXT_OFFSET_R6, in0
203 add loc21 = CONTEXT_OFFSET_R7, in0
204 add loc22 = CONTEXT_OFFSET_SP, in0
205 add loc23 = CONTEXT_OFFSET_R13, in0
206
207 add loc24 = CONTEXT_OFFSET_PC, in0
208 add loc25 = CONTEXT_OFFSET_B1, in0
209 add loc26 = CONTEXT_OFFSET_B2, in0
210 add loc27 = CONTEXT_OFFSET_B3, in0
211 add loc28 = CONTEXT_OFFSET_B4, in0
212 add loc29 = CONTEXT_OFFSET_B5, in0
213
214 add loc30 = CONTEXT_OFFSET_PR, in0
215
216 add loc31 = CONTEXT_OFFSET_F2, in0
217 add loc32 = CONTEXT_OFFSET_F3, in0
218 add loc33 = CONTEXT_OFFSET_F4, in0
219 add loc34 = CONTEXT_OFFSET_F5, in0
220
221 add loc35 = CONTEXT_OFFSET_F16, in0
222 add loc36 = CONTEXT_OFFSET_F17, in0
223 add loc37 = CONTEXT_OFFSET_F18, in0
224 add loc38 = CONTEXT_OFFSET_F19, in0
225 add loc39 = CONTEXT_OFFSET_F20, in0
226 add loc40 = CONTEXT_OFFSET_F21, in0
227 add loc41 = CONTEXT_OFFSET_F22, in0
228 add loc42 = CONTEXT_OFFSET_F23, in0
229 add loc43 = CONTEXT_OFFSET_F24, in0
230 add loc44 = CONTEXT_OFFSET_F25, in0
231 add loc45 = CONTEXT_OFFSET_F26, in0
232 add loc46 = CONTEXT_OFFSET_F27, in0
233 add loc47 = CONTEXT_OFFSET_F28, in0
234 add loc48 = CONTEXT_OFFSET_F29, in0
235 add loc49 = CONTEXT_OFFSET_F30, in0
236 add loc50 = CONTEXT_OFFSET_F31, in0 ;;
237
238 ld8 loc0 = [loc9] /* load ar.pfs */
239 ld8 loc1 = [loc10] /* load ar.unat (caller) */
240 ld8 loc2 = [loc11] /* load ar.unat (callee) */
241 ld8 loc3 = [loc12] /* load ar.rsc */
242 ld8 loc4 = [loc13] /* load ar.bsp */
243 ld8 loc5 = [loc14] /* load ar.rnat */
244 ld8 loc6 = [loc15] /* load ar.lc */
245 ld8 loc7 = [loc16] /* load ar.fpsr */
246
247 .auto
248
249 /*
250 * Invalidate the ALAT
251 */
252 invala
253
254 /*
255 * Put RSE to enforced lazy mode.
256 * So that ar.bspstore and ar.rnat can be written.
257 */
258 movl loc8 = ~3
259 and loc8 = loc3, loc8
260 mov ar.rsc = loc8
261
262 /*
263 * Flush dirty registers to backing store.
264 * We do this because we want the following move
265 * to ar.bspstore to assign the same value to ar.bsp.
266 */
267 flushrs
268
269 /*
270 * Restore application registers
271 */
272 mov ar.bspstore = loc4 /* rse.bspload = ar.bsp = ar.bspstore = loc4 */
273 mov ar.rnat = loc5
274 mov ar.pfs = loc0
275 mov ar.rsc = loc3
276 mov ar.fpsr = loc7
277
278 .explicit
279
280 mov ar.unat = loc2 ;;
281 mov ar.lc = loc6
282
283 /*
284 * Restore general registers including NaT bits
285 */
286 ld8.fill r1 = [loc17] ;;
287 ld8.fill r4 = [loc18] ;;
288 ld8.fill r5 = [loc19] ;;
289 ld8.fill r6 = [loc20] ;;
290 ld8.fill r7 = [loc21] ;;
291 ld8.fill r12 = [loc22] ;; /* restore sp */
292 ld8.fill r13 = [loc23] ;;
293
294 /*
295 * Restore branch registers
296 */
297 ld8 loc2 = [loc24] /* restore pc */
298 ld8 loc3 = [loc25]
299 ld8 loc4 = [loc26]
300 ld8 loc5 = [loc27]
301 ld8 loc6 = [loc28]
302 ld8 loc7 = [loc29] ;;
303 mov b0 = loc2
304 mov b1 = loc3
305 mov b2 = loc4
306 mov b3 = loc5
307 mov b4 = loc6
308 mov b5 = loc7 ;;
309
310 /*
311 * Restore predicate registers
312 */
313 ld8 loc2 = [loc30] ;;
314 mov pr = loc2, ~0
315
316 /*
317 * Restore floating-point registers.
318 */
319 ldf.fill f2 = [loc31]
320 ldf.fill f3 = [loc32]
321 ldf.fill f4 = [loc33]
322 ldf.fill f5 = [loc34]
323
324 ldf.fill f16 = [loc35]
325 ldf.fill f17 = [loc36]
326 ldf.fill f18 = [loc37]
327 ldf.fill f19 = [loc38]
328 ldf.fill f20 = [loc39]
329 ldf.fill f21 = [loc40]
330 ldf.fill f22 = [loc41]
331 ldf.fill f23 = [loc42]
332 ldf.fill f24 = [loc43]
333 ldf.fill f25 = [loc44]
334 ldf.fill f26 = [loc45]
335 ldf.fill f27 = [loc46]
336 ldf.fill f28 = [loc47]
337 ldf.fill f29 = [loc48]
338 ldf.fill f30 = [loc49]
339 ldf.fill f31 = [loc50]
340
341 mov ar.unat = loc1
342
343 mov r8 = r0 /* context_restore returns 0 */
344 br.ret.sptk.many b0
345FUNCTION_END(context_restore_arch)
346
Note: See TracBrowser for help on using the repository browser.