1/* Jump to a new context powerpc32 common. 2 Copyright (C) 2005-2022 Free Software Foundation, Inc. 3 This file is part of the GNU C Library. 4 5 The GNU C Library is free software; you can redistribute it and/or 6 modify it under the terms of the GNU Lesser General Public 7 License as published by the Free Software Foundation; either 8 version 2.1 of the License, or (at your option) any later version. 9 10 The GNU C Library is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public 16 License along with the GNU C Library; if not, see 17 <https://www.gnu.org/licenses/>. */ 18 19/* This is the common implementation of setcontext for powerpc32. 20 It not complete in itself should be included in to a framework that 21 defines: 22 __CONTEXT_FUNC_NAME 23 and if appropriate: 24 __CONTEXT_ENABLE_FPRS 25 __CONTEXT_ENABLE_VRS 26 Any architecture that implements the Vector unit is assumed to also 27 implement the floating unit. */ 28 29/* Stack frame offsets. */ 30#define _FRAME_BACKCHAIN 0 31#define _FRAME_LR_SAVE 4 32#define _FRAME_PARM_SAVE1 8 33#define _FRAME_PARM_SAVE2 12 34#define _FRAME_PARM_SAVE3 16 35#define _FRAME_PARM_SAVE4 20 36 37#ifdef __CONTEXT_ENABLE_VRS 38 .machine "altivec" 39#endif 40ENTRY(__CONTEXT_FUNC_NAME) 41 mflr r0 42 stwu r1,-16(r1) 43 cfi_adjust_cfa_offset (16) 44 stw r0,20(r1) 45 cfi_offset (lr, _FRAME_LR_SAVE) 46 stw r31,12(r1) 47 cfi_offset(r31,-4) 48 lwz r31,_UC_REGS_PTR(r3) 49 50 /* Restore the signal mask */ 51 li r5,0 52 addi r4,r3,_UC_SIGMASK 53 li r3,SIG_SETMASK 54 bl __sigprocmask@local 55 cmpwi r3,0 56 bne 3f /* L(error_exit) */ 57 58#ifdef PIC 59 mflr r8 60# define got_label GENERATE_GOT_LABEL (__CONTEXT_FUNC_NAME) 61 SETUP_GOT_ACCESS(r7,got_label) 62 addis r7,r7,_GLOBAL_OFFSET_TABLE_-got_label@ha 63 addi r7,r7,_GLOBAL_OFFSET_TABLE_-got_label@l 64# ifdef SHARED 65 lwz r7,_rtld_global_ro@got(r7) 66 mtlr r8 67 lwz r7,RTLD_GLOBAL_RO_DL_HWCAP_OFFSET+LOWORD(r7) 68# else 69 lwz r7,_dl_hwcap@got(r7) 70 mtlr r8 71 lwz r7,LOWORD(r7) 72# endif 73#else 74 lis r7,(_dl_hwcap+LOWORD)@ha 75 lwz r7,(_dl_hwcap+LOWORD)@l(r7) 76#endif 77 78#ifdef __CONTEXT_ENABLE_FPRS 79# ifdef __CONTEXT_ENABLE_VRS 80 andis. r6,r7,(PPC_FEATURE_HAS_ALTIVEC >> 16) 81 la r10,(_UC_VREGS)(r31) 82 beq 2f /* L(has_no_vec) */ 83 84 lwz r0,(32*16)(r10) 85 li r9,(32*16) 86 cmpwi r0,0 87 mtspr VRSAVE,r0 88 beq 2f /* L(has_no_vec) */ 89 90 lvx v19,r9,r10 91 la r9,(16)(r10) 92 93 lvx v0,0,r10 94 lvx v1,0,r9 95 addi r10,r10,32 96 addi r9,r9,32 97 98 mtvscr v19 99 lvx v2,0,r10 100 lvx v3,0,r9 101 addi r10,r10,32 102 addi r9,r9,32 103 104 lvx v4,0,r10 105 lvx v5,0,r9 106 addi r10,r10,32 107 addi r9,r9,32 108 109 lvx v6,0,r10 110 lvx v7,0,r9 111 addi r10,r10,32 112 addi r9,r9,32 113 114 lvx v8,0,r10 115 lvx v9,0,r9 116 addi r10,r10,32 117 addi r9,r9,32 118 119 lvx v10,0,r10 120 lvx v11,0,r9 121 addi r10,r10,32 122 addi r9,r9,32 123 124 lvx v12,0,r10 125 lvx v13,0,r9 126 addi r10,r10,32 127 addi r9,r9,32 128 129 lvx v14,0,r10 130 lvx v15,0,r9 131 addi r10,r10,32 132 addi r9,r9,32 133 134 lvx v16,0,r10 135 lvx v17,0,r9 136 addi r10,r10,32 137 addi r9,r9,32 138 139 lvx v18,0,r10 140 lvx v19,0,r9 141 addi r10,r10,32 142 addi r9,r9,32 143 144 lvx v20,0,r10 145 lvx v21,0,r9 146 addi r10,r10,32 147 addi r9,r9,32 148 149 lvx v22,0,r10 150 lvx v23,0,r9 151 addi r10,r10,32 152 addi r9,r9,32 153 154 lvx v24,0,r10 155 lvx v25,0,r9 156 addi r10,r10,32 157 addi r9,r9,32 158 159 lvx v26,0,r10 160 lvx v27,0,r9 161 addi r10,r10,32 162 addi r9,r9,32 163 164 lvx v28,0,r10 165 lvx v29,0,r9 166 addi r10,r10,32 167 addi r9,r9,32 168 169 lvx v30,0,r10 170 lvx v31,0,r9 171 addi r10,r10,32 172 addi r9,r9,32 173 174 lvx v10,0,r10 175 lvx v11,0,r9 176 1772: /* L(has_no_vec): */ 178# endif /* __CONTEXT_ENABLE_VRS */ 179 /* Restore the floating-point registers */ 180 lfd fp31,_UC_FREGS+(32*8)(r31) 181 lfd fp0,_UC_FREGS+(0*8)(r31) 182# ifdef _ARCH_PWR6 183 /* Use the extended four-operand version of the mtfsf insn. */ 184 mtfsf 0xff,fp31,1,0 185# else 186 .machine push 187 .machine "power6" 188 /* Availability of DFP indicates a 64-bit FPSCR. */ 189 andi. r6,r7,PPC_FEATURE_HAS_DFP 190 beq 7f 191 /* Use the extended four-operand version of the mtfsf insn. */ 192 mtfsf 0xff,fp31,1,0 193 b 8f 194 /* Continue to operate on the FPSCR as if it were 32-bits. */ 1957: mtfsf 0xff,fp31 1968: .machine pop 197# endif /* _ARCH_PWR6 */ 198 lfd fp1,_UC_FREGS+(1*8)(r31) 199 lfd fp2,_UC_FREGS+(2*8)(r31) 200 lfd fp3,_UC_FREGS+(3*8)(r31) 201 lfd fp4,_UC_FREGS+(4*8)(r31) 202 lfd fp5,_UC_FREGS+(5*8)(r31) 203 lfd fp6,_UC_FREGS+(6*8)(r31) 204 lfd fp7,_UC_FREGS+(7*8)(r31) 205 lfd fp8,_UC_FREGS+(8*8)(r31) 206 lfd fp9,_UC_FREGS+(9*8)(r31) 207 lfd fp10,_UC_FREGS+(10*8)(r31) 208 lfd fp11,_UC_FREGS+(11*8)(r31) 209 lfd fp12,_UC_FREGS+(12*8)(r31) 210 lfd fp13,_UC_FREGS+(13*8)(r31) 211 lfd fp14,_UC_FREGS+(14*8)(r31) 212 lfd fp15,_UC_FREGS+(15*8)(r31) 213 lfd fp16,_UC_FREGS+(16*8)(r31) 214 lfd fp17,_UC_FREGS+(17*8)(r31) 215 lfd fp18,_UC_FREGS+(18*8)(r31) 216 lfd fp19,_UC_FREGS+(19*8)(r31) 217 lfd fp20,_UC_FREGS+(20*8)(r31) 218 lfd fp21,_UC_FREGS+(21*8)(r31) 219 lfd fp22,_UC_FREGS+(22*8)(r31) 220 lfd fp23,_UC_FREGS+(23*8)(r31) 221 lfd fp24,_UC_FREGS+(24*8)(r31) 222 lfd fp25,_UC_FREGS+(25*8)(r31) 223 lfd fp26,_UC_FREGS+(26*8)(r31) 224 lfd fp27,_UC_FREGS+(27*8)(r31) 225 lfd fp28,_UC_FREGS+(28*8)(r31) 226 lfd fp29,_UC_FREGS+(29*8)(r31) 227 lfd fp30,_UC_FREGS+(30*8)(r31) 228 lfd fp31,_UC_FREGS+(31*8)(r31) 229#endif /* __CONTEXT_ENABLE_FPRS */ 230 231 /* Restore LR and CCR, and set CTR to the NIP value */ 232 lwz r3,_UC_GREGS+(PT_LNK*4)(r31) 233 lwz r4,_UC_GREGS+(PT_NIP*4)(r31) 234 lwz r5,_UC_GREGS+(PT_CCR*4)(r31) 235 mtlr r3 236 mtctr r4 237 mtcr r5 238 239 /* Restore the general registers */ 240 lwz r1,_UC_GREGS+(PT_R1*4)(r31) 241 lwz r3,_UC_GREGS+(PT_R3*4)(r31) 242 lwz r4,_UC_GREGS+(PT_R4*4)(r31) 243 lwz r5,_UC_GREGS+(PT_R5*4)(r31) 244 lwz r6,_UC_GREGS+(PT_R6*4)(r31) 245 lwz r7,_UC_GREGS+(PT_R7*4)(r31) 246 lwz r8,_UC_GREGS+(PT_R8*4)(r31) 247 lwz r9,_UC_GREGS+(PT_R9*4)(r31) 248 lwz r10,_UC_GREGS+(PT_R10*4)(r31) 249 lwz r11,_UC_GREGS+(PT_R11*4)(r31) 250 lwz r12,_UC_GREGS+(PT_R12*4)(r31) 251 lwz r13,_UC_GREGS+(PT_R13*4)(r31) 252 lwz r14,_UC_GREGS+(PT_R14*4)(r31) 253 lwz r15,_UC_GREGS+(PT_R15*4)(r31) 254 lwz r16,_UC_GREGS+(PT_R16*4)(r31) 255 lwz r17,_UC_GREGS+(PT_R17*4)(r31) 256 lwz r18,_UC_GREGS+(PT_R18*4)(r31) 257 lwz r19,_UC_GREGS+(PT_R19*4)(r31) 258 lwz r20,_UC_GREGS+(PT_R20*4)(r31) 259 lwz r21,_UC_GREGS+(PT_R21*4)(r31) 260 lwz r22,_UC_GREGS+(PT_R22*4)(r31) 261 lwz r23,_UC_GREGS+(PT_R23*4)(r31) 262 lwz r24,_UC_GREGS+(PT_R24*4)(r31) 263 lwz r25,_UC_GREGS+(PT_R25*4)(r31) 264 lwz r26,_UC_GREGS+(PT_R26*4)(r31) 265 lwz r27,_UC_GREGS+(PT_R27*4)(r31) 266 lwz r28,_UC_GREGS+(PT_R28*4)(r31) 267 lwz r29,_UC_GREGS+(PT_R29*4)(r31) 268 lwz r30,_UC_GREGS+(PT_R30*4)(r31) 269 lwz r31,_UC_GREGS+(PT_R31*4)(r31) 270 271 bctr 272 2733: /* L(error_exit): */ 274 lwz r31,12(r1) 275 lwz r0,20(r1) 276 addi r1,r1,16 277 mtlr r0 278 blr 279 280END (__CONTEXT_FUNC_NAME) 281