1/* This file contains the exception-handling save_world and 2 * restore_world routines, which need to do a run-time check to see if 3 * they should save and restore the vector registers. 4 * 5 * Copyright (C) 2004-2018 Free Software Foundation, Inc. 6 * 7 * This file is free software; you can redistribute it and/or modify it 8 * under the terms of the GNU General Public License as published by the 9 * Free Software Foundation; either version 3, or (at your option) any 10 * later version. 11 * 12 * This file is distributed in the hope that it will be useful, but 13 * WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * General Public License for more details. 16 * 17 * Under Section 7 of GPL version 3, you are granted additional 18 * permissions described in the GCC Runtime Library Exception, version 19 * 3.1, as published by the Free Software Foundation. 20 * 21 * You should have received a copy of the GNU General Public License and 22 * a copy of the GCC Runtime Library Exception along with this program; 23 * see the files COPYING3 and COPYING.RUNTIME respectively. If not, see 24 * <http://www.gnu.org/licenses/>. 25 */ 26 27#ifndef __ppc64__ 28 29 .machine ppc7400 30.data 31 .align 2 32 33#ifdef __DYNAMIC__ 34 35.non_lazy_symbol_pointer 36L_has_vec$non_lazy_ptr: 37 .indirect_symbol __cpu_has_altivec 38 .long 0 39#else 40 41/* For static, "pretend" we have a non-lazy-pointer. */ 42 43L_has_vec$non_lazy_ptr: 44 .long __cpu_has_altivec 45 46#endif 47 48 49.text 50 .align 2 51 52/* save_world and rest_world save/restore F14-F31 and possibly V20-V31 53 (assuming you have a CPU with vector registers; we use a global var 54 provided by the System Framework to determine this.) 55 56 SAVE_WORLD takes R0 (the caller`s caller`s return address) and R11 57 (the stack frame size) as parameters. It returns the updated VRsave 58 in R0 if we`re on a CPU with vector regs. 59 60 For gcc3 onward, we need to save and restore CR as well, since scheduled 61 prologs can cause comparisons to be moved before calls to save_world. 62 63 USES: R0 R11 R12 */ 64 65.private_extern save_world 66save_world: 67 stw r0,8(r1) 68 mflr r0 69 bcl 20,31,Ls$pb 70Ls$pb: mflr r12 71 addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Ls$pb) 72 lwz r12,lo16(L_has_vec$non_lazy_ptr-Ls$pb)(r12) 73 mtlr r0 74 lwz r12,0(r12) 75 /* grab CR */ 76 mfcr r0 77 /* test HAS_VEC */ 78 cmpwi r12,0 79 stfd f14,-144(r1) 80 stfd f15,-136(r1) 81 stfd f16,-128(r1) 82 stfd f17,-120(r1) 83 stfd f18,-112(r1) 84 stfd f19,-104(r1) 85 stfd f20,-96(r1) 86 stfd f21,-88(r1) 87 stfd f22,-80(r1) 88 stfd f23,-72(r1) 89 stfd f24,-64(r1) 90 stfd f25,-56(r1) 91 stfd f26,-48(r1) 92 stfd f27,-40(r1) 93 stfd f28,-32(r1) 94 stfd f29,-24(r1) 95 stfd f30,-16(r1) 96 stfd f31,-8(r1) 97 stmw r13,-220(r1) 98 /* stash CR */ 99 stw r0,4(r1) 100 /* set R12 pointing at Vector Reg save area */ 101 addi r12,r1,-224 102 /* allocate stack frame */ 103 stwux r1,r1,r11 104 /* ...but return if HAS_VEC is zero */ 105 bne+ L$saveVMX 106 /* Not forgetting to restore CR. */ 107 mtcr r0 108 blr 109 110L$saveVMX: 111 /* We're saving Vector regs too. */ 112 /* Restore CR from R0. No More Branches! */ 113 mtcr r0 114 115 /* We should really use VRSAVE to figure out which vector regs 116 we actually need to save and restore. Some other time :-/ */ 117 118 li r11,-192 119 stvx v20,r11,r12 120 li r11,-176 121 stvx v21,r11,r12 122 li r11,-160 123 stvx v22,r11,r12 124 li r11,-144 125 stvx v23,r11,r12 126 li r11,-128 127 stvx v24,r11,r12 128 li r11,-112 129 stvx v25,r11,r12 130 li r11,-96 131 stvx v26,r11,r12 132 li r11,-80 133 stvx v27,r11,r12 134 li r11,-64 135 stvx v28,r11,r12 136 li r11,-48 137 stvx v29,r11,r12 138 li r11,-32 139 stvx v30,r11,r12 140 mfspr r0,VRsave 141 li r11,-16 142 stvx v31,r11,r12 143 stw r0,0(r12) /* VRsave lives at -224(R1). */ 144 ori r0,r0,0xfff /* We just saved these. */ 145 mtspr VRsave,r0 146 blr 147 148/* rest_world is jumped to, not called, so no need to worry about LR. 149 clobbers R0, R7, R11 and R12. This just undoes the work done above. */ 150 151 .private_extern rest_world 152rest_world: 153 154 lwz r11, 0(r1) /* Pickup previous SP */ 155 li r7, 0 /* Stack offset is zero, r10 is ignored. */ 156 b Lrest_world_eh_r7 157 158/* eh_rest_world_r10 is jumped to, not called, so no need to worry about LR. 159 R10 is the C++ EH stack adjust parameter, we return to the caller`s caller. 160 161 clobbers: R0, R7, R11 and R12 162 uses : R10 163 RETURNS : C++ EH Data registers (R3 - R6). */ 164 165 .private_extern eh_rest_world_r10 166eh_rest_world_r10: 167 168 lwz r11, 0(r1) /* Pickup previous SP */ 169 mr r7,r10 /* Stack offset. */ 170 171 /* pickup the C++ EH data regs (R3 - R6.) */ 172 lwz r6,-420(r11) 173 lwz r5,-424(r11) 174 lwz r4,-428(r11) 175 lwz r3,-432(r11) 176 177 /* Fall through to Lrest_world_eh_r7. */ 178 179/* When we are doing the exception-handling epilog, R7 contains the offset to 180 add to the SP. 181 182 clobbers: R0, R11 and R12 183 uses : R7. */ 184 185Lrest_world_eh_r7: 186 /* See if we have Altivec. */ 187 bcl 20,31,Lr7$pb 188Lr7$pb: mflr r12 189 190 addis r12,r12,ha16(L_has_vec$non_lazy_ptr-Lr7$pb) 191 lwz r12,lo16(L_has_vec$non_lazy_ptr-Lr7$pb)(r12) 192 lwz r12,0(r12) /* R12 := HAS_VEC */ 193 cmpwi r12,0 194 lmw r13,-220(r11) 195 beq L.rest_world_fp_eh 196 197 /* We have Altivec, restore VRsave and V20..V31 */ 198 lwz r0,-224(r11) 199 li r12,-416 200 mtspr VRsave,r0 201 lvx v20,r11,r12 202 li r12,-400 203 lvx v21,r11,r12 204 li r12,-384 205 lvx v22,r11,r12 206 li r12,-368 207 lvx v23,r11,r12 208 li r12,-352 209 lvx v24,r11,r12 210 li r12,-336 211 lvx v25,r11,r12 212 li r12,-320 213 lvx v26,r11,r12 214 li r12,-304 215 lvx v27,r11,r12 216 li r12,-288 217 lvx v28,r11,r12 218 li r12,-272 219 lvx v29,r11,r12 220 li r12,-256 221 lvx v30,r11,r12 222 li r12,-240 223 lvx v31,r11,r12 224 225L.rest_world_fp_eh: 226 lwz r0,4(r11) /* recover saved CR */ 227 lfd f14,-144(r11) 228 lfd f15,-136(r11) 229 lfd f16,-128(r11) 230 lfd f17,-120(r11) 231 lfd f18,-112(r11) 232 lfd f19,-104(r11) 233 lfd f20,-96(r11) 234 lfd f21,-88(r11) 235 lfd f22,-80(r11) 236 lfd f23,-72(r11) 237 lfd f24,-64(r11) 238 lfd f25,-56(r11) 239 lfd f26,-48(r11) 240 lfd f27,-40(r11) 241 lfd f28,-32(r11) 242 lfd f29,-24(r11) 243 lfd f30,-16(r11) 244 mtcr r0 /* restore the saved cr. */ 245 lwz r0, 8(r11) /* Pick up the 'real' return address. */ 246 lfd f31,-8(r11) 247 mtctr r0 /* exception-handler ret. address */ 248 add r1,r11,r7 /* set SP to original value + R7 offset */ 249 bctr 250#endif 251/* we should never be called on ppc64 for this ... */ 252/* Done. */ 253