1 /* libunwind - a platform-independent unwind library
2 Copyright (C) 2004 Hewlett-Packard Co
3 Contributed by David Mosberger-Tang <davidm@hpl.hp.com>
5 This file is part of libunwind.
7 Permission is hereby granted, free of charge, to any person obtaining
8 a copy of this software and associated documentation files (the
9 "Software"), to deal in the Software without restriction, including
10 without limitation the rights to use, copy, modify, merge, publish,
11 distribute, sublicense, and/or sell copies of the Software, and to
12 permit persons to whom the Software is furnished to do so, subject to
13 the following conditions:
15 The above copyright notice and this permission notice shall be
16 included in all copies or substantial portions of the Software.
18 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19 EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21 NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
22 LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
23 OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
24 WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. */
26 #include "ucontext_i.h"
28 #define GR(n) (SC_GR + (n)*8)
29 #define BR(n) (SC_BR + (n)*8)
30 #define FR(n) (SC_FR + (n)*16)
32 /* This should be compatible to the libc's getcontext(), except that
33 the sc->sc_mask field is always cleared and that the name is
34 prefixed with _Uia64_ so we don't step on the application's
38 .protected _Uia64_getcontext
39 .global _Uia64_getcontext
40 .proc _Uia64_getcontext
43 alloc rPFS = ar.pfs, 1, 0, 0, 0 // M2
44 mov rPR = pr // I0, 2 cycles
45 add r2 = GR(1), in0 // I1
49 mov.m rUNAT = ar.unat // M2, 5 cycles
51 st8.spill [r2] = r1, (SC_FLAGS - GR(1)) // M3
52 dep.z rFLAGS = -1, IA64_SC_FLAG_SYNCHRONOUS_BIT, 1 // I0, 1 cycle
55 mov.m rRSC = ar.rsc // M2, 12 cyc.
56 st8 [r2] = rFLAGS, (SC_PR - SC_FLAGS) // M3
60 mov.m rBSP = ar.bsp // M2, 12 cyc.
61 st8 [r2] = rPR, (GR(12) - SC_PR) // M3
65 mov.m rFPSR = ar.fpsr // M2, 12 cyc.
66 st8.spill [r2] = r12, (GR(4) - GR(12)) // M3
70 stf.spill [r3] = f2 // M2
71 stf.spill [r8] = f16 // M3
76 stf.spill [r9] = f24, (FR(31) - FR(24)) // M2
77 mov rB0 = b0 // I0, 2 cycles
80 stf.spill [r9] = f31 // M2
81 st8.spill [r2] = r4, (GR(5) - GR(4)) // M3, bank 1
82 mov rB1 = b1 // I0, 2 cycles
85 .mem.offset 0,0; st8.spill [r2] = r5, (GR(6) - GR(5)) // M4, bank 0
86 .mem.offset 8,0; st8.spill [r3] = r7, (BR(0) - GR(7)) // M3, bank 0
87 mov rB2 = b2 // I0, 2 cycles
90 st8.spill [r2] = r6, (BR(1) - GR(6)) // M2, bank 1
91 st8 [r3] = rB0, (BR(4) - BR(0)) // M3, bank 1
92 mov rB4 = b4 // I0, 2 cycles
95 mov.m rNAT = ar.unat // M2, 5 cycles
96 st8 [r2] = rB1, (BR(2) - BR(1)) // M3, bank 0
100 st8 [r2] = rB2, (BR(3) - BR(2)) // M2, bank 1
101 st8 [r3] = rB4, (SC_LC - BR(4)) // M3, bank 1
102 mov rB5 = b5 // I0, 2 cycles
105 and rTMP = ~0x3, rRSC // M0
106 add rPOS = GR(0), in0 // rPOS <- &sc_gr[0] // M1
107 mov.i rLC = ar.lc // I0, 2 cycles
110 mov.m ar.rsc = rTMP // put RSE into lazy mode // M2, ? cycles
111 st8 [r2] = rB3, (BR(5) - BR(3)) // M3, bank 0
112 extr.u rPOS = rPOS, 3, 6 // get NaT bitnr for r0 // I0
115 mov.m rRNAT = ar.rnat // M2, 5 cycles
116 st8 [r2] = rB5, (SC_PFS - BR(5)) // M3, bank 0
117 sub rCPOS = 64, rPOS // I0
120 st8 [r2] = rPFS, (SC_UNAT - SC_PFS) // M2
121 st8 [r3] = rLC, (SC_BSP - SC_LC) // M3
122 shr.u rTMP = rNAT, rPOS // I0, 3 cycles
125 st8 [r2] = rUNAT, (SC_FPSR - SC_UNAT) // M2
126 st8 [r3] = rBSP // M3
130 st8 [r2] = rFPSR, (SC_RNAT - SC_FPSR) // M2
131 stf.spill [r8] = f3, (FR(4) - FR(3)) // M3
135 stf.spill [r8] = f4, (FR(17) - FR(4)) // M2
136 stf.spill [r9] = f5, (FR(19) - FR(5)) // M3
137 shl rNAT = rNAT, rCPOS // I0, 3 cycles
140 st8 [r2] = rRNAT, (SC_NAT - SC_RNAT) // M2
141 stf.spill [r8] = f17, (FR(18) - FR(17)) // M3
145 stf.spill [r8] = f18, (FR(20) - FR(18)) // M2
146 stf.spill [r9] = f19, (FR(21) - FR(19)) // M3
150 stf.spill [r8] = f20, (FR(22) - FR(20)) // M2
151 stf.spill [r9] = f21, (FR(23) - FR(21)) // M3
152 or rNAT = rNAT, rTMP // I0
155 st8 [r2] = rNAT // M2
156 stf.spill [r8] = f22, (FR(25) - FR(22)) // M3
158 stf.spill [r9] = f23, (FR(26) - FR(23)) // M2
159 stf.spill [r8] = f25, (FR(27) - FR(25)) // M3
161 stf.spill [r9] = f26, (FR(28) - FR(26)) // M2
162 stf.spill [r8] = f27, (FR(29) - FR(27)) // M3
164 mov.m ar.rsc = rRSC // restore RSE mode // M2
165 stf.spill [r9] = f28, (FR(30) - FR(28)) // M3
167 mov.m ar.unat = rUNAT // restore caller's UNaT // M2
168 stf.spill [r8] = f29 // M3
170 stf.spill [r9] = f30 // M2
173 .endp _Uia64_getcontext
175 /* We do not need executable stack. */
176 .section .note.GNU-stack,"",@progbits