1 | // Copyright 2019 The Marl Authors. |
2 | // |
3 | // Licensed under the Apache License, Version 2.0 (the "License"); |
4 | // you may not use this file except in compliance with the License. |
5 | // You may obtain a copy of the License at |
6 | // |
7 | // https://www.apache.org/licenses/LICENSE-2.0 |
8 | // |
9 | // Unless required by applicable law or agreed to in writing, software |
10 | // distributed under the License is distributed on an "AS IS" BASIS, |
11 | // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
12 | // See the License for the specific language governing permissions and |
13 | // limitations under the License. |
14 | |
15 | #if defined(__powerpc64__) |
16 | |
17 | #define MARL_BUILD_ASM 1 |
18 | #include "osfiber_asm_ppc64.h" |
19 | |
20 | // void marl_fiber_swap(marl_fiber_context* from, const marl_fiber_context* to) |
21 | // r3: from |
22 | // r4: to |
23 | .text |
24 | .global marl_fiber_swap |
25 | .align 4 |
26 | #if !defined(_CALL_ELF) || (_CALL_ELF != 2) |
27 | .global .marl_fiber_swap |
28 | .pushsection ".opd" ,"aw" |
29 | marl_fiber_swap: |
30 | .quad .marl_fiber_swap |
31 | .quad .TOC.@tocbase |
32 | .quad 0 |
33 | .popsection |
34 | .type .marl_fiber_swap,@function |
35 | .marl_fiber_swap: |
36 | #else |
37 | .type marl_fiber_swap @function |
38 | marl_fiber_swap: |
39 | #endif |
40 | |
41 | // Store non-volatile registers |
42 | std 1, MARL_REG_R1(3) |
43 | std 2, MARL_REG_R2(3) |
44 | std 13, MARL_REG_R13(3) |
45 | std 14, MARL_REG_R14(3) |
46 | std 15, MARL_REG_R15(3) |
47 | std 16, MARL_REG_R16(3) |
48 | std 17, MARL_REG_R17(3) |
49 | std 18, MARL_REG_R18(3) |
50 | std 19, MARL_REG_R19(3) |
51 | std 20, MARL_REG_R20(3) |
52 | std 21, MARL_REG_R21(3) |
53 | std 22, MARL_REG_R22(3) |
54 | std 23, MARL_REG_R23(3) |
55 | std 24, MARL_REG_R24(3) |
56 | std 25, MARL_REG_R25(3) |
57 | std 26, MARL_REG_R26(3) |
58 | std 27, MARL_REG_R27(3) |
59 | std 28, MARL_REG_R28(3) |
60 | std 29, MARL_REG_R29(3) |
61 | std 30, MARL_REG_R30(3) |
62 | std 31, MARL_REG_R31(3) |
63 | |
64 | // Store special registers |
65 | mflr 5 |
66 | std 5, MARL_REG_LR(3) |
67 | mfcr 5 |
68 | std 5, MARL_REG_CCR(3) |
69 | |
70 | // Store non-volatile floating point registers |
71 | stfd 14, MARL_REG_FPR14(3) |
72 | stfd 15, MARL_REG_FPR15(3) |
73 | stfd 16, MARL_REG_FPR16(3) |
74 | stfd 17, MARL_REG_FPR17(3) |
75 | stfd 18, MARL_REG_FPR18(3) |
76 | stfd 19, MARL_REG_FPR19(3) |
77 | stfd 20, MARL_REG_FPR20(3) |
78 | stfd 21, MARL_REG_FPR21(3) |
79 | stfd 22, MARL_REG_FPR22(3) |
80 | stfd 23, MARL_REG_FPR23(3) |
81 | stfd 24, MARL_REG_FPR24(3) |
82 | stfd 25, MARL_REG_FPR25(3) |
83 | stfd 26, MARL_REG_FPR26(3) |
84 | stfd 27, MARL_REG_FPR27(3) |
85 | stfd 28, MARL_REG_FPR28(3) |
86 | stfd 29, MARL_REG_FPR29(3) |
87 | stfd 30, MARL_REG_FPR30(3) |
88 | stfd 31, MARL_REG_FPR31(3) |
89 | |
90 | // Store non-volatile altivec registers |
91 | #ifdef __ALTIVEC__ |
92 | li 5, MARL_REG_VMX |
93 | stvxl 20, 3, 5 |
94 | addi 5, 5, 16 |
95 | stvxl 21, 3, 5 |
96 | addi 5, 5, 16 |
97 | stvxl 22, 3, 5 |
98 | addi 5, 5, 16 |
99 | stvxl 23, 3, 5 |
100 | addi 5, 5, 16 |
101 | stvxl 24, 3, 5 |
102 | addi 5, 5, 16 |
103 | stvxl 25, 3, 5 |
104 | addi 5, 5, 16 |
105 | stvxl 26, 3, 5 |
106 | addi 5, 5, 16 |
107 | stvxl 27, 3, 5 |
108 | addi 5, 5, 16 |
109 | stvxl 28, 3, 5 |
110 | addi 5, 5, 16 |
111 | stvxl 29, 3, 5 |
112 | addi 5, 5, 16 |
113 | stvxl 30, 3, 5 |
114 | addi 5, 5, 16 |
115 | stvxl 31, 3, 5 |
116 | |
117 | mfvrsave 5 |
118 | stw 5, MARL_REG_VRSAVE(3) |
119 | #endif // __ALTIVEC__ |
120 | |
121 | // Load non-volatile registers |
122 | ld 1, MARL_REG_R1(4) |
123 | ld 2, MARL_REG_R2(4) |
124 | ld 13, MARL_REG_R13(4) |
125 | ld 14, MARL_REG_R14(4) |
126 | ld 15, MARL_REG_R15(4) |
127 | ld 16, MARL_REG_R16(4) |
128 | ld 17, MARL_REG_R17(4) |
129 | ld 18, MARL_REG_R18(4) |
130 | ld 19, MARL_REG_R19(4) |
131 | ld 20, MARL_REG_R20(4) |
132 | ld 21, MARL_REG_R21(4) |
133 | ld 22, MARL_REG_R22(4) |
134 | ld 23, MARL_REG_R23(4) |
135 | ld 24, MARL_REG_R24(4) |
136 | ld 25, MARL_REG_R25(4) |
137 | ld 26, MARL_REG_R26(4) |
138 | ld 27, MARL_REG_R27(4) |
139 | ld 28, MARL_REG_R28(4) |
140 | ld 29, MARL_REG_R29(4) |
141 | ld 30, MARL_REG_R30(4) |
142 | ld 31, MARL_REG_R31(4) |
143 | |
144 | // Load non-volatile floating point registers |
145 | lfd 14, MARL_REG_FPR14(4) |
146 | lfd 15, MARL_REG_FPR15(4) |
147 | lfd 16, MARL_REG_FPR16(4) |
148 | lfd 17, MARL_REG_FPR17(4) |
149 | lfd 18, MARL_REG_FPR18(4) |
150 | lfd 19, MARL_REG_FPR19(4) |
151 | lfd 20, MARL_REG_FPR20(4) |
152 | lfd 21, MARL_REG_FPR21(4) |
153 | lfd 22, MARL_REG_FPR22(4) |
154 | lfd 23, MARL_REG_FPR23(4) |
155 | lfd 24, MARL_REG_FPR24(4) |
156 | lfd 25, MARL_REG_FPR25(4) |
157 | lfd 26, MARL_REG_FPR26(4) |
158 | lfd 27, MARL_REG_FPR27(4) |
159 | lfd 28, MARL_REG_FPR28(4) |
160 | lfd 29, MARL_REG_FPR29(4) |
161 | lfd 30, MARL_REG_FPR30(4) |
162 | lfd 31, MARL_REG_FPR31(4) |
163 | |
164 | // Load non-volatile altivec registers |
165 | #ifdef __ALTIVEC__ |
166 | li 5, MARL_REG_VMX |
167 | lvxl 20, 4, 5 |
168 | addi 5, 5, 16 |
169 | lvxl 21, 4, 5 |
170 | addi 5, 5, 16 |
171 | lvxl 22, 4, 5 |
172 | addi 5, 5, 16 |
173 | lvxl 23, 4, 5 |
174 | addi 5, 5, 16 |
175 | lvxl 24, 4, 5 |
176 | addi 5, 5, 16 |
177 | lvxl 25, 4, 5 |
178 | addi 5, 5, 16 |
179 | lvxl 26, 4, 5 |
180 | addi 5, 5, 16 |
181 | lvxl 27, 4, 5 |
182 | addi 5, 5, 16 |
183 | lvxl 28, 4, 5 |
184 | addi 5, 5, 16 |
185 | lvxl 29, 4, 5 |
186 | addi 5, 5, 16 |
187 | lvxl 30, 4, 5 |
188 | addi 5, 5, 16 |
189 | lvxl 31, 4, 5 |
190 | |
191 | lwz 5, MARL_REG_VRSAVE(4) |
192 | mtvrsave 5 |
193 | #endif // __ALTIVEC__ |
194 | |
195 | // Load parameters and entrypoint |
196 | ld 12, MARL_REG_LR(4) |
197 | ld 3, MARL_REG_R3(4) |
198 | ld 4, MARL_REG_R4(4) |
199 | mtlr 12 |
200 | |
201 | // Branch to entrypoint |
202 | blr |
203 | |
204 | #endif // defined(__powerpc64__) |
205 | |