1 /* libunwind - a platform-independent unwind library 2 Copyright (C) 2004 Hewlett-Packard Co 3 Contributed by David Mosberger-Tang <davidm (at) hpl.hp.com> 4 5 This file is part of libunwind. 6 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: 14 15 The above copyright notice and this permission notice shall be 16 included in all copies or substantial portions of the Software. 17 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. */ 25 26 #include "ucontext_i.h" 27 28 #define GR(n) (SC_GR + (n)*8) 29 #define BR(n) (SC_BR + (n)*8) 30 #define FR(n) (SC_FR + (n)*16) 31 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 35 name-space. */ 36 37 .align 32 38 .protected _Uia64_getcontext 39 .global _Uia64_getcontext 40 .proc _Uia64_getcontext 41 _Uia64_getcontext: 42 .prologue 43 alloc rPFS = ar.pfs, 1, 0, 0, 0 // M2 44 mov rPR = pr // I0, 2 cycles 45 add r2 = GR(1), in0 // I1 46 ;; 47 48 .save ar.unat, rUNAT 49 mov.m rUNAT = ar.unat // M2, 5 cycles 50 .body 51 st8.spill [r2] = r1, (SC_FLAGS - GR(1)) // M3 52 dep.z rFLAGS = -1, IA64_SC_FLAG_SYNCHRONOUS_BIT, 1 // I0, 1 cycle 53 ;; 54 55 mov.m rRSC = ar.rsc // M2, 12 cyc. 56 st8 [r2] = rFLAGS, (SC_PR - SC_FLAGS) // M3 57 add r3 = FR(2), in0 58 ;; 59 60 mov.m rBSP = ar.bsp // M2, 12 cyc. 61 st8 [r2] = rPR, (GR(12) - SC_PR) // M3 62 add r8 = FR(16), in0 63 ;; 64 65 mov.m rFPSR = ar.fpsr // M2, 12 cyc. 66 st8.spill [r2] = r12, (GR(4) - GR(12)) // M3 67 add r9 = FR(24), in0 68 ;; 69 70 stf.spill [r3] = f2 // M2 71 stf.spill [r8] = f16 // M3 72 add r3 = GR(7), in0 73 ;; 74 75 flushrs // M0 76 stf.spill [r9] = f24, (FR(31) - FR(24)) // M2 77 mov rB0 = b0 // I0, 2 cycles 78 ;; 79 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 83 ;; 84 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 88 ;; 89 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 93 ;; 94 95 mov.m rNAT = ar.unat // M2, 5 cycles 96 st8 [r2] = rB1, (BR(2) - BR(1)) // M3, bank 0 97 mov rB3 = b3 98 ;; 99 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 103 ;; 104 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 108 ;; 109 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 113 ;; 114 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 118 ;; 119 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 123 ;; 124 125 st8 [r2] = rUNAT, (SC_FPSR - SC_UNAT) // M2 126 st8 [r3] = rBSP // M3 127 add r8 = FR(3), in0 128 ;; 129 130 st8 [r2] = rFPSR, (SC_RNAT - SC_FPSR) // M2 131 stf.spill [r8] = f3, (FR(4) - FR(3)) // M3 132 add r9 = FR(5), in0 133 ;; 134 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 138 ;; 139 140 st8 [r2] = rRNAT, (SC_NAT - SC_RNAT) // M2 141 stf.spill [r8] = f17, (FR(18) - FR(17)) // M3 142 nop.i 0 143 ;; 144 145 stf.spill [r8] = f18, (FR(20) - FR(18)) // M2 146 stf.spill [r9] = f19, (FR(21) - FR(19)) // M3 147 nop.i 0 148 ;; 149 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 153 ;; 154 155 st8 [r2] = rNAT // M2 156 stf.spill [r8] = f22, (FR(25) - FR(22)) // M3 157 ;; 158 stf.spill [r9] = f23, (FR(26) - FR(23)) // M2 159 stf.spill [r8] = f25, (FR(27) - FR(25)) // M3 160 ;; 161 stf.spill [r9] = f26, (FR(28) - FR(26)) // M2 162 stf.spill [r8] = f27, (FR(29) - FR(27)) // M3 163 ;; 164 mov.m ar.rsc = rRSC // restore RSE mode // M2 165 stf.spill [r9] = f28, (FR(30) - FR(28)) // M3 166 ;; 167 mov.m ar.unat = rUNAT // restore caller's UNaT // M2 168 stf.spill [r8] = f29 // M3 169 ;; 170 stf.spill [r9] = f30 // M2 171 mov r8 = 0 172 br.ret.sptk.many rp 173 .endp _Uia64_getcontext 174 #ifdef __linux__ 175 /* We do not need executable stack. */ 176 .section .note.GNU-stack,"",@progbits 177 #endif 178