]>
Commit | Line | Data |
---|---|---|
e9ce8d39 A |
1 | /* |
2 | * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. | |
3 | * | |
4 | * @APPLE_LICENSE_HEADER_START@ | |
5 | * | |
59e0d9fe A |
6 | * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved. |
7 | * | |
734aad71 A |
8 | * This file contains Original Code and/or Modifications of Original Code |
9 | * as defined in and that are subject to the Apple Public Source License | |
10 | * Version 2.0 (the 'License'). You may not use this file except in | |
11 | * compliance with the License. Please obtain a copy of the License at | |
12 | * http://www.opensource.apple.com/apsl/ and read it before using this | |
13 | * file. | |
14 | * | |
15 | * The Original Code and all software distributed under the License are | |
16 | * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER | |
e9ce8d39 A |
17 | * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, |
18 | * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, | |
734aad71 A |
19 | * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. |
20 | * Please see the License for the specific language governing rights and | |
21 | * limitations under the License. | |
e9ce8d39 A |
22 | * |
23 | * @APPLE_LICENSE_HEADER_END@ | |
24 | */ | |
25 | ||
e9ce8d39 A |
26 | /* |
27 | * Copyright (c) 1998 Apple Computer, Inc. All rights reserved. | |
28 | * | |
29 | * File: sys/ppc/_longjmp.s | |
30 | * | |
31 | * Implements _longjmp() | |
32 | * | |
33 | * History: | |
34 | * 8 September 1998 Matt Watson (mwatson@apple.com) | |
35 | * Created. Derived from longjmp.s | |
36 | */ | |
3b2a1fe8 | 37 | |
59e0d9fe A |
38 | /* We use mode-independent "g" opcodes such as "lg", and/or |
39 | * mode-independent macros such as MI_CALL_EXTERNAL. These expand | |
40 | * into word operations when targeting __ppc__, and into doubleword | |
41 | * operations when targeting __ppc64__. | |
42 | */ | |
43 | #include <architecture/ppc/mode_independent_asm.h> | |
3b2a1fe8 | 44 | |
59e0d9fe | 45 | #include "_setjmp.h" |
3b2a1fe8 | 46 | |
59e0d9fe A |
47 | #define __APPLE_API_PRIVATE |
48 | #include <machine/cpu_capabilities.h> | |
49 | #undef __APPLE_API_PRIVATE | |
3b2a1fe8 | 50 | |
59e0d9fe | 51 | #define VRSave 256 |
3b2a1fe8 | 52 | |
3b2a1fe8 | 53 | |
59e0d9fe A |
54 | /* int _longjmp(jmp_buf env, int val); */ |
55 | ||
56 | MI_ENTRY_POINT(__longjmp) | |
57 | lg r6,JMP_addr_at_setjmp(r3) | |
58 | lbz r7, _COMM_PAGE_ALTIVEC(0) | |
59 | cmpg cr1,r3,r6 ; jmpbuf still at same address? | |
60 | cmpwi cr2,r7,0 ; Altivec available? (using non-volatile cr) | |
61 | beq++ cr1,LRestoreVRs ; jmpbuf has not moved | |
3b2a1fe8 A |
62 | |
63 | ; jmp_buf was moved since setjmp (or is uninitialized.) | |
64 | ; We must move VRs and FPRs to be quadword aligned at present address. | |
65 | ||
59e0d9fe A |
66 | stg r3,JMP_addr_at_setjmp(r3) ; update, in case we longjmp to this again |
67 | mr r31,r4 ; save "val" arg across memmove | |
68 | mr r30,r3 ; and jmp_buf ptr | |
3b2a1fe8 A |
69 | addi r3,r3,JMP_vr_base_addr |
70 | addi r4,r6,JMP_vr_base_addr | |
59e0d9fe A |
71 | clrrgi r3,r3,4 ; r3 <- QW aligned addr where they should be |
72 | clrrgi r4,r4,4 ; r4 <- QW aligned addr where they originally were | |
73 | sub r7,r4,r6 ; r7 <- offset of VRs/FPRs within jmp_buf | |
74 | add r4,r30,r7 ; r4 <- where they are now | |
3b2a1fe8 | 75 | li r5,(JMP_buf_end - JMP_vr_base_addr) |
59e0d9fe A |
76 | |
77 | MI_CALL_EXTERNAL(_memmove) | |
78 | ||
79 | mr r3,r30 ; restore parameters | |
80 | mr r4,r31 | |
3b2a1fe8 A |
81 | |
82 | ; Restore VRs iff any | |
59e0d9fe | 83 | ; cr2 - beq if AltiVec not available |
3b2a1fe8 A |
84 | |
85 | LRestoreVRs: | |
59e0d9fe | 86 | lg r0,JMP_vrsave(r3) ; get VRSAVE at setjmp() |
3b2a1fe8 | 87 | addi r6,r3,JMP_vr_base_addr |
59e0d9fe A |
88 | beq-- cr2,LRestoreFPRs ; AltiVec not available so skip |
89 | cmpwi r0,0 ; any live VRs? | |
90 | mtspr VRSave,r0 ; update VRSAVE whether 0 or not | |
91 | beq++ LRestoreFPRs ; VRSAVE is 0 so no VRs to reload | |
92 | lvx v20,0,r6 | |
93 | li r7,16*1 | |
94 | lvx v21,r7,r6 | |
95 | li r7,16*2 | |
96 | lvx v22,r7,r6 | |
97 | li r7,16*3 | |
98 | lvx v23,r7,r6 | |
99 | li r7,16*4 | |
100 | lvx v24,r7,r6 | |
101 | li r7,16*5 | |
102 | lvx v25,r7,r6 | |
103 | li r7,16*6 | |
104 | lvx v26,r7,r6 | |
105 | li r7,16*7 | |
106 | lvx v27,r7,r6 | |
107 | li r7,16*8 | |
108 | lvx v28,r7,r6 | |
109 | li r7,16*9 | |
110 | lvx v29,r7,r6 | |
111 | li r7,16*10 | |
112 | lvx v30,r7,r6 | |
113 | li r7,16*11 | |
114 | lvx v31,r7,r6 | |
3b2a1fe8 | 115 | |
59e0d9fe | 116 | ; Restore FPRs |
3b2a1fe8 A |
117 | |
118 | LRestoreFPRs: | |
3b2a1fe8 | 119 | addi r6,r3,JMP_fp_base_addr |
59e0d9fe A |
120 | lfd f0,JMP_fpscr(r3) ; get FPSCR from non-sliding section of jmpbuf |
121 | clrrgi r6,r6,4 ; mask off low 4 bits to qw align | |
122 | lfd f14,0*8(r6) | |
123 | lfd f15,1*8(r6) | |
124 | lfd f16,2*8(r6) | |
125 | lfd f17,3*8(r6) | |
126 | lfd f18,4*8(r6) | |
127 | lfd f19,5*8(r6) | |
128 | lfd f20,6*8(r6) | |
129 | lfd f21,7*8(r6) | |
130 | lfd f22,8*8(r6) | |
131 | lfd f23,9*8(r6) | |
132 | lfd f24,10*8(r6) | |
133 | lfd f25,11*8(r6) | |
134 | lfd f26,12*8(r6) | |
135 | lfd f27,13*8(r6) | |
136 | lfd f28,14*8(r6) | |
137 | lfd f29,15*8(r6) | |
138 | lfd f30,16*8(r6) | |
139 | lfd f31,17*8(r6) | |
140 | mtfsf 0xFF,f0 ; restore entire FPSCR | |
3b2a1fe8 A |
141 | |
142 | ; Restore GPRs | |
143 | ||
59e0d9fe A |
144 | lg r5, JMP_cr(r3) ; r5 <- CR |
145 | lg r6, JMP_lr(r3) ; r6 <- LR (ie, return addres) | |
146 | cmplgi r4,0 ; is return value 0? (not permitted) | |
147 | lg r1, JMP_r1 (r3) | |
148 | lg r2, JMP_r2 (r3) | |
149 | lg r13, JMP_r13(r3) | |
150 | lg r14, JMP_r14(r3) | |
151 | lg r15, JMP_r15(r3) | |
152 | lg r16, JMP_r16(r3) | |
153 | lg r17, JMP_r17(r3) | |
154 | mtcrf 0x20,r5 ; restore cr2 (we only restore non-volatile CRs) | |
155 | lg r18, JMP_r18(r3) | |
156 | lg r19, JMP_r19(r3) | |
157 | lg r20, JMP_r20(r3) | |
158 | lg r21, JMP_r21(r3) | |
159 | mtctr r6 ; set up return address, avoiding LR since it will mispredict | |
160 | lg r22, JMP_r22(r3) | |
161 | lg r23, JMP_r23(r3) | |
162 | lg r24, JMP_r24(r3) | |
163 | lg r25, JMP_r25(r3) | |
164 | mtcrf 0x10,r5 ; restore cr3 | |
165 | lg r26, JMP_r26(r3) | |
166 | lg r27, JMP_r27(r3) | |
167 | lg r28, JMP_r28(r3) | |
168 | lg r29, JMP_r29(r3) | |
169 | mtcrf 0x08,r5 ; restore cr4 | |
170 | lg r30, JMP_r30(r3) | |
171 | lg r31, JMP_r31(r3) | |
172 | mr r3,r4 ; move return code into position (cr0 is set on r4) | |
173 | bnectr++ ; return code was not 0 | |
174 | li r3, 1 ; cannot return zero from longjmp(), so return 1 instead | |
175 | bctr | |
e9ce8d39 | 176 |