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"
29marl_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
38marl_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