|
1 |
|
2 # HG changeset patch |
|
3 # User Marcin Juszkiewicz <mjuszkiewicz@redhat.com> |
|
4 # Date 1393440196 18000 |
|
5 # Node ID d56b5c1a557348d4ac14a4d1ea7a5b5d240e3647 |
|
6 # Parent 6a46f53ad944b44385398822d7bcf7621a785d91 |
|
7 Bug 963024 - AArch64 support for XPCOM. r=froydnj |
|
8 |
|
9 diff --git a/xpcom/reflect/xptcall/src/md/unix/moz.build b/xpcom/reflect/xptcall/src/md/unix/moz.build |
|
10 --- a/xpcom/reflect/xptcall/src/md/unix/moz.build |
|
11 +++ b/xpcom/reflect/xptcall/src/md/unix/moz.build |
|
12 @@ -144,16 +144,23 @@ if CONFIG['OS_ARCH'] == 'NetBSD': |
|
13 if CONFIG['OS_TEST'] in ('amiga', 'atari', 'hp300', 'mac68k', 'mvme68k', |
|
14 'next68k', 'sun3', 'sun3x', 'x68k'): |
|
15 SOURCES += [ |
|
16 'xptcinvoke_netbsd_m68k.cpp', |
|
17 'xptcstubs_netbsd_m68k.cpp' |
|
18 ] |
|
19 |
|
20 if CONFIG['OS_ARCH'] == 'Linux': |
|
21 + if CONFIG['OS_TEST'] == 'aarch64': |
|
22 + SOURCES += [ |
|
23 + 'xptcinvoke_aarch64.cpp', |
|
24 + 'xptcinvoke_asm_aarch64.s', |
|
25 + 'xptcstubs_aarch64.cpp', |
|
26 + 'xptcstubs_asm_aarch64.s', |
|
27 + ] |
|
28 if CONFIG['OS_TEST'] == 'm68k': |
|
29 SOURCES += [ |
|
30 'xptcinvoke_linux_m68k.cpp', |
|
31 'xptcstubs_linux_m68k.cpp', |
|
32 ] |
|
33 if CONFIG['OS_TEST'].find('mips') != -1: |
|
34 if CONFIG['OS_TEST'].find('mips64') != -1: |
|
35 SOURCES += [ |
|
36 diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_aarch64.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_aarch64.cpp |
|
37 new file mode 100644 |
|
38 --- /dev/null |
|
39 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_aarch64.cpp |
|
40 @@ -0,0 +1,136 @@ |
|
41 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
42 +/* This Source Code Form is subject to the terms of the Mozilla Public |
|
43 + * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
44 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
45 + |
|
46 +/* Platform specific code to invoke XPCOM methods on native objects */ |
|
47 + |
|
48 +#include "xptcprivate.h" |
|
49 + |
|
50 +#if !defined(__aarch64__) |
|
51 +#error "This code is for Linux AArch64 only." |
|
52 +#endif |
|
53 + |
|
54 + |
|
55 +/* "Procedure Call Standard for the ARM 64-bit Architecture" document, sections |
|
56 + * "5.4 Parameter Passing" and "6.1.2 Procedure Calling" contain all the |
|
57 + * needed information. |
|
58 + * |
|
59 + * http://infocenter.arm.com/help/topic/com.arm.doc.ihi0042d/IHI0042D_aapcs.pdf |
|
60 + */ |
|
61 + |
|
62 +#ifndef __AARCH64EL__ |
|
63 +#error "Only little endian compatibility was tested" |
|
64 +#endif |
|
65 + |
|
66 +/* |
|
67 + * Allocation of integer function arguments initially to registers r1-r7 |
|
68 + * and then to stack. Handling of 'that' argument which goes to register r0 |
|
69 + * is handled separately and does not belong here. |
|
70 + * |
|
71 + * 'ireg_args' - pointer to the current position in the buffer, |
|
72 + * corresponding to the register arguments |
|
73 + * 'stack_args' - pointer to the current position in the buffer, |
|
74 + * corresponding to the arguments on stack |
|
75 + * 'end' - pointer to the end of the registers argument |
|
76 + * buffer. |
|
77 + */ |
|
78 +static inline void alloc_word(uint64_t* &ireg_args, |
|
79 + uint64_t* &stack_args, |
|
80 + uint64_t* end, |
|
81 + uint64_t data) |
|
82 +{ |
|
83 + if (ireg_args < end) { |
|
84 + *ireg_args = data; |
|
85 + ireg_args++; |
|
86 + } else { |
|
87 + *stack_args = data; |
|
88 + stack_args++; |
|
89 + } |
|
90 +} |
|
91 + |
|
92 +static inline void alloc_double(double* &freg_args, |
|
93 + uint64_t* &stack_args, |
|
94 + double* end, |
|
95 + double data) |
|
96 +{ |
|
97 + if (freg_args < end) { |
|
98 + *freg_args = data; |
|
99 + freg_args++; |
|
100 + } else { |
|
101 + memcpy(stack_args, &data, sizeof(data)); |
|
102 + stack_args++; |
|
103 + } |
|
104 +} |
|
105 + |
|
106 +static inline void alloc_float(double* &freg_args, |
|
107 + uint64_t* &stack_args, |
|
108 + double* end, |
|
109 + float data) |
|
110 +{ |
|
111 + if (freg_args < end) { |
|
112 + memcpy(freg_args, &data, sizeof(data)); |
|
113 + freg_args++; |
|
114 + } else { |
|
115 + memcpy(stack_args, &data, sizeof(data)); |
|
116 + stack_args++; |
|
117 + } |
|
118 +} |
|
119 + |
|
120 + |
|
121 +extern "C" void |
|
122 +invoke_copy_to_stack(uint64_t* stk, uint64_t *end, |
|
123 + uint32_t paramCount, nsXPTCVariant* s) |
|
124 +{ |
|
125 + uint64_t *ireg_args = stk; |
|
126 + uint64_t *ireg_end = ireg_args + 8; |
|
127 + double *freg_args = (double *)ireg_end; |
|
128 + double *freg_end = freg_args + 8; |
|
129 + uint64_t *stack_args = (uint64_t *)freg_end; |
|
130 + |
|
131 + // leave room for 'that' argument in x0 |
|
132 + ++ireg_args; |
|
133 + |
|
134 + for (uint32_t i = 0; i < paramCount; i++, s++) { |
|
135 + if (s->IsPtrData()) { |
|
136 + alloc_word(ireg_args, stack_args, ireg_end, (uint64_t)s->ptr); |
|
137 + continue; |
|
138 + } |
|
139 + // According to the ABI, integral types that are smaller than 8 bytes |
|
140 + // are to be passed in 8-byte registers or 8-byte stack slots. |
|
141 + switch (s->type) { |
|
142 + case nsXPTType::T_FLOAT: |
|
143 + alloc_float(freg_args, stack_args, freg_end, s->val.f); |
|
144 + break; |
|
145 + case nsXPTType::T_DOUBLE: |
|
146 + alloc_double(freg_args, stack_args, freg_end, s->val.d); |
|
147 + break; |
|
148 + case nsXPTType::T_I8: alloc_word(ireg_args, stk, end, s->val.i8); break; |
|
149 + case nsXPTType::T_I16: alloc_word(ireg_args, stk, end, s->val.i16); break; |
|
150 + case nsXPTType::T_I32: alloc_word(ireg_args, stk, end, s->val.i32); break; |
|
151 + case nsXPTType::T_I64: alloc_word(ireg_args, stk, end, s->val.i64); break; |
|
152 + case nsXPTType::T_U8: alloc_word(ireg_args, stk, end, s->val.u8); break; |
|
153 + case nsXPTType::T_U16: alloc_word(ireg_args, stk, end, s->val.u16); break; |
|
154 + case nsXPTType::T_U32: alloc_word(ireg_args, stk, end, s->val.u32); break; |
|
155 + case nsXPTType::T_U64: alloc_word(ireg_args, stk, end, s->val.u64); break; |
|
156 + case nsXPTType::T_BOOL: alloc_word(ireg_args, stk, end, s->val.b); break; |
|
157 + case nsXPTType::T_CHAR: alloc_word(ireg_args, stk, end, s->val.c); break; |
|
158 + case nsXPTType::T_WCHAR: alloc_word(ireg_args, stk, end, s->val.wc); break; |
|
159 + default: |
|
160 + // all the others are plain pointer types |
|
161 + alloc_word(ireg_args, stack_args, ireg_end, |
|
162 + reinterpret_cast<uint64_t>(s->val.p)); |
|
163 + break; |
|
164 + } |
|
165 + } |
|
166 +} |
|
167 + |
|
168 +extern "C" nsresult _NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, |
|
169 + uint32_t paramCount, nsXPTCVariant* params); |
|
170 + |
|
171 +EXPORT_XPCOM_API(nsresult) |
|
172 +NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, |
|
173 + uint32_t paramCount, nsXPTCVariant* params) |
|
174 +{ |
|
175 + return _NS_InvokeByIndex(that, methodIndex, paramCount, params); |
|
176 +} |
|
177 diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_aarch64.s b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_aarch64.s |
|
178 new file mode 100644 |
|
179 --- /dev/null |
|
180 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcinvoke_asm_aarch64.s |
|
181 @@ -0,0 +1,67 @@ |
|
182 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
183 +/* This Source Code Form is subject to the terms of the Mozilla Public |
|
184 + * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
185 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
186 + |
|
187 + .section ".text" |
|
188 + .globl _NS_InvokeByIndex |
|
189 + .type _NS_InvokeByIndex,@function |
|
190 + |
|
191 +/* |
|
192 + * _NS_InvokeByIndex(nsISupports* that, uint32_t methodIndex, |
|
193 + * uint32_t paramCount, nsXPTCVariant* params) |
|
194 + */ |
|
195 + |
|
196 +_NS_InvokeByIndex: |
|
197 + # set up frame |
|
198 + stp x29, x30, [sp,#-32]! |
|
199 + mov x29, sp |
|
200 + stp x19, x20, [sp,#16] |
|
201 + |
|
202 + # save methodIndex across function calls |
|
203 + mov w20, w1 |
|
204 + |
|
205 + # end of stack area passed to invoke_copy_to_stack |
|
206 + mov x1, sp |
|
207 + |
|
208 + # assume 8 bytes of stack for each argument with 16-byte alignment |
|
209 + add w19, w2, #1 |
|
210 + and w19, w19, #0xfffffffe |
|
211 + sub sp, sp, w19, uxth #3 |
|
212 + |
|
213 + # temporary place to store args passed in r0-r7,v0-v7 |
|
214 + sub sp, sp, #128 |
|
215 + |
|
216 + # save 'that' on stack |
|
217 + str x0, [sp] |
|
218 + |
|
219 + # start of stack area passed to invoke_copy_to_stack |
|
220 + mov x0, sp |
|
221 + bl invoke_copy_to_stack |
|
222 + |
|
223 + # load arguments passed in r0-r7 |
|
224 + ldp x6, x7, [sp, #48] |
|
225 + ldp x4, x5, [sp, #32] |
|
226 + ldp x2, x3, [sp, #16] |
|
227 + ldp x0, x1, [sp],#64 |
|
228 + |
|
229 + # load arguments passed in v0-v7 |
|
230 + ldp d6, d7, [sp, #48] |
|
231 + ldp d4, d5, [sp, #32] |
|
232 + ldp d2, d3, [sp, #16] |
|
233 + ldp d0, d1, [sp],#64 |
|
234 + |
|
235 + # call the method |
|
236 + ldr x16, [x0] |
|
237 + add x16, x16, w20, uxth #3 |
|
238 + ldr x16, [x16] |
|
239 + blr x16 |
|
240 + |
|
241 + add sp, sp, w19, uxth #3 |
|
242 + ldp x19, x20, [sp,#16] |
|
243 + ldp x29, x30, [sp],#32 |
|
244 + ret |
|
245 + |
|
246 + .size _NS_InvokeByIndex, . - _NS_InvokeByIndex |
|
247 + |
|
248 + |
|
249 diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_aarch64.cpp b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_aarch64.cpp |
|
250 new file mode 100644 |
|
251 --- /dev/null |
|
252 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_aarch64.cpp |
|
253 @@ -0,0 +1,219 @@ |
|
254 +/* -*- Mode: C; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */ |
|
255 +/* This Source Code Form is subject to the terms of the Mozilla Public |
|
256 + * License, v. 2.0. If a copy of the MPL was not distributed with this |
|
257 + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
|
258 + |
|
259 +#include "xptcprivate.h" |
|
260 +#include "xptiprivate.h" |
|
261 + |
|
262 +#ifndef __AARCH64EL__ |
|
263 +#error "Only little endian compatibility was tested" |
|
264 +#endif |
|
265 + |
|
266 +/* |
|
267 + * This is for AArch64 ABI |
|
268 + * |
|
269 + * When we're called, the "gp" registers are stored in gprData and |
|
270 + * the "fp" registers are stored in fprData. Each array has 8 regs |
|
271 + * but first reg in gprData is a placeholder for 'self'. |
|
272 + */ |
|
273 +extern "C" nsresult |
|
274 +PrepareAndDispatch(nsXPTCStubBase* self, uint32_t methodIndex, uint64_t* args, |
|
275 + uint64_t *gprData, double *fprData) |
|
276 +{ |
|
277 +#define PARAM_BUFFER_COUNT 16 |
|
278 +#define PARAM_GPR_COUNT 8 |
|
279 +#define PARAM_FPR_COUNT 8 |
|
280 + |
|
281 + nsXPTCMiniVariant paramBuffer[PARAM_BUFFER_COUNT]; |
|
282 + nsXPTCMiniVariant* dispatchParams = NULL; |
|
283 + const nsXPTMethodInfo* info; |
|
284 + nsresult result = NS_ERROR_FAILURE; |
|
285 + |
|
286 + NS_ASSERTION(self,"no self"); |
|
287 + |
|
288 + self->mEntry->GetMethodInfo(uint16_t(methodIndex), &info); |
|
289 + NS_ASSERTION(info,"no method info"); |
|
290 + |
|
291 + uint32_t paramCount = info->GetParamCount(); |
|
292 + |
|
293 + // setup variant array pointer |
|
294 + if (paramCount > PARAM_BUFFER_COUNT) { |
|
295 + dispatchParams = new nsXPTCMiniVariant[paramCount]; |
|
296 + } else { |
|
297 + dispatchParams = paramBuffer; |
|
298 + } |
|
299 + NS_ASSERTION(dispatchParams,"no place for params"); |
|
300 + |
|
301 + uint64_t* ap = args; |
|
302 + uint32_t next_gpr = 1; // skip first arg which is 'self' |
|
303 + uint32_t next_fpr = 0; |
|
304 + for (uint32_t i = 0; i < paramCount; i++) { |
|
305 + const nsXPTParamInfo& param = info->GetParam(i); |
|
306 + const nsXPTType& type = param.GetType(); |
|
307 + nsXPTCMiniVariant* dp = &dispatchParams[i]; |
|
308 + |
|
309 + if (param.IsOut() || !type.IsArithmetic()) { |
|
310 + if (next_gpr < PARAM_GPR_COUNT) { |
|
311 + dp->val.p = (void*)gprData[next_gpr++]; |
|
312 + } else { |
|
313 + dp->val.p = (void*)*ap++; |
|
314 + } |
|
315 + continue; |
|
316 + } |
|
317 + |
|
318 + switch (type) { |
|
319 + case nsXPTType::T_I8: |
|
320 + if (next_gpr < PARAM_GPR_COUNT) { |
|
321 + dp->val.i8 = (int8_t)gprData[next_gpr++]; |
|
322 + } else { |
|
323 + dp->val.i8 = (int8_t)*ap++; |
|
324 + } |
|
325 + break; |
|
326 + |
|
327 + case nsXPTType::T_I16: |
|
328 + if (next_gpr < PARAM_GPR_COUNT) { |
|
329 + dp->val.i16 = (int16_t)gprData[next_gpr++]; |
|
330 + } else { |
|
331 + dp->val.i16 = (int16_t)*ap++; |
|
332 + } |
|
333 + break; |
|
334 + |
|
335 + case nsXPTType::T_I32: |
|
336 + if (next_gpr < PARAM_GPR_COUNT) { |
|
337 + dp->val.i32 = (int32_t)gprData[next_gpr++]; |
|
338 + } else { |
|
339 + dp->val.i32 = (int32_t)*ap++; |
|
340 + } |
|
341 + break; |
|
342 + |
|
343 + case nsXPTType::T_I64: |
|
344 + if (next_gpr < PARAM_GPR_COUNT) { |
|
345 + dp->val.i64 = (int64_t)gprData[next_gpr++]; |
|
346 + } else { |
|
347 + dp->val.i64 = (int64_t)*ap++; |
|
348 + } |
|
349 + break; |
|
350 + |
|
351 + case nsXPTType::T_U8: |
|
352 + if (next_gpr < PARAM_GPR_COUNT) { |
|
353 + dp->val.u8 = (uint8_t)gprData[next_gpr++]; |
|
354 + } else { |
|
355 + dp->val.u8 = (uint8_t)*ap++; |
|
356 + } |
|
357 + break; |
|
358 + |
|
359 + case nsXPTType::T_U16: |
|
360 + if (next_gpr < PARAM_GPR_COUNT) { |
|
361 + dp->val.u16 = (uint16_t)gprData[next_gpr++]; |
|
362 + } else { |
|
363 + dp->val.u16 = (uint16_t)*ap++; |
|
364 + } |
|
365 + break; |
|
366 + |
|
367 + case nsXPTType::T_U32: |
|
368 + if (next_gpr < PARAM_GPR_COUNT) { |
|
369 + dp->val.u32 = (uint32_t)gprData[next_gpr++]; |
|
370 + } else { |
|
371 + dp->val.u32 = (uint32_t)*ap++; |
|
372 + } |
|
373 + break; |
|
374 + |
|
375 + case nsXPTType::T_U64: |
|
376 + if (next_gpr < PARAM_GPR_COUNT) { |
|
377 + dp->val.u64 = (uint64_t)gprData[next_gpr++]; |
|
378 + } else { |
|
379 + dp->val.u64 = (uint64_t)*ap++; |
|
380 + } |
|
381 + break; |
|
382 + |
|
383 + case nsXPTType::T_FLOAT: |
|
384 + if (next_fpr < PARAM_FPR_COUNT) { |
|
385 + memcpy(&dp->val.f, &fprData[next_fpr++], sizeof(dp->val.f)); |
|
386 + } else { |
|
387 + memcpy(&dp->val.f, ap++, sizeof(dp->val.f)); |
|
388 + } |
|
389 + break; |
|
390 + |
|
391 + case nsXPTType::T_DOUBLE: |
|
392 + if (next_fpr < PARAM_FPR_COUNT) { |
|
393 + memcpy(&dp->val.d, &fprData[next_fpr++], sizeof(dp->val.d)); |
|
394 + } else { |
|
395 + memcpy(&dp->val.d, ap++, sizeof(dp->val.d)); |
|
396 + } |
|
397 + break; |
|
398 + |
|
399 + case nsXPTType::T_BOOL: |
|
400 + if (next_gpr < PARAM_GPR_COUNT) { |
|
401 + dp->val.b = (bool)gprData[next_gpr++]; |
|
402 + } else { |
|
403 + dp->val.b = (bool)*ap++; |
|
404 + } |
|
405 + break; |
|
406 + |
|
407 + case nsXPTType::T_CHAR: |
|
408 + if (next_gpr < PARAM_GPR_COUNT) { |
|
409 + dp->val.c = (char)gprData[next_gpr++]; |
|
410 + } else { |
|
411 + dp->val.c = (char)*ap++; |
|
412 + } |
|
413 + break; |
|
414 + |
|
415 + case nsXPTType::T_WCHAR: |
|
416 + if (next_gpr < PARAM_GPR_COUNT) { |
|
417 + dp->val.wc = (wchar_t)gprData[next_gpr++]; |
|
418 + } else { |
|
419 + dp->val.wc = (wchar_t)*ap++; |
|
420 + } |
|
421 + break; |
|
422 + |
|
423 + default: |
|
424 + NS_ASSERTION(0, "bad type"); |
|
425 + break; |
|
426 + } |
|
427 + } |
|
428 + |
|
429 + result = self->mOuter->CallMethod((uint16_t)methodIndex, info, dispatchParams); |
|
430 + |
|
431 + if (dispatchParams != paramBuffer) { |
|
432 + delete [] dispatchParams; |
|
433 + } |
|
434 + |
|
435 + return result; |
|
436 +} |
|
437 + |
|
438 +// Load w17 with the constant 'n' and branch to SharedStub(). |
|
439 +# define STUB_ENTRY(n) \ |
|
440 + __asm__ ( \ |
|
441 + ".section \".text\" \n\t" \ |
|
442 + ".align 2\n\t" \ |
|
443 + ".if "#n" < 10 \n\t" \ |
|
444 + ".globl _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \ |
|
445 + ".hidden _ZN14nsXPTCStubBase5Stub"#n"Ev \n\t" \ |
|
446 + ".type _ZN14nsXPTCStubBase5Stub"#n"Ev,@function \n\n" \ |
|
447 + "_ZN14nsXPTCStubBase5Stub"#n"Ev: \n\t" \ |
|
448 + ".elseif "#n" < 100 \n\t" \ |
|
449 + ".globl _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \ |
|
450 + ".hidden _ZN14nsXPTCStubBase6Stub"#n"Ev \n\t" \ |
|
451 + ".type _ZN14nsXPTCStubBase6Stub"#n"Ev,@function \n\n" \ |
|
452 + "_ZN14nsXPTCStubBase6Stub"#n"Ev: \n\t" \ |
|
453 + ".elseif "#n" < 1000 \n\t" \ |
|
454 + ".globl _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \ |
|
455 + ".hidden _ZN14nsXPTCStubBase7Stub"#n"Ev \n\t" \ |
|
456 + ".type _ZN14nsXPTCStubBase7Stub"#n"Ev,@function \n\n" \ |
|
457 + "_ZN14nsXPTCStubBase7Stub"#n"Ev: \n\t" \ |
|
458 + ".else \n\t" \ |
|
459 + ".err \"stub number "#n" >= 1000 not yet supported\"\n" \ |
|
460 + ".endif \n\t" \ |
|
461 + "mov w17,#"#n" \n\t" \ |
|
462 + "b SharedStub \n" \ |
|
463 +); |
|
464 + |
|
465 +#define SENTINEL_ENTRY(n) \ |
|
466 + nsresult nsXPTCStubBase::Sentinel##n() \ |
|
467 +{ \ |
|
468 + NS_ASSERTION(0,"nsXPTCStubBase::Sentinel called"); \ |
|
469 + return NS_ERROR_NOT_IMPLEMENTED; \ |
|
470 +} |
|
471 + |
|
472 +#include "xptcstubsdef.inc" |
|
473 diff --git a/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_aarch64.s b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_aarch64.s |
|
474 new file mode 100644 |
|
475 --- /dev/null |
|
476 +++ b/xpcom/reflect/xptcall/src/md/unix/xptcstubs_asm_aarch64.s |
|
477 @@ -0,0 +1,39 @@ |
|
478 +# This Source Code Form is subject to the terms of the Mozilla Public |
|
479 +# License, v. 2.0. If a copy of the MPL was not distributed with this |
|
480 +# file, You can obtain one at http://mozilla.org/MPL/2.0/. |
|
481 + |
|
482 + .set NGPREGS,8 |
|
483 + .set NFPREGS,8 |
|
484 + |
|
485 + .section ".text" |
|
486 + .globl SharedStub |
|
487 + .hidden SharedStub |
|
488 + .type SharedStub,@function |
|
489 +SharedStub: |
|
490 + stp x29, x30, [sp,#-16]! |
|
491 + mov x29, sp |
|
492 + |
|
493 + sub sp, sp, #8*(NGPREGS+NFPREGS) |
|
494 + stp x0, x1, [sp, #64+(0*8)] |
|
495 + stp x2, x3, [sp, #64+(2*8)] |
|
496 + stp x4, x5, [sp, #64+(4*8)] |
|
497 + stp x6, x7, [sp, #64+(6*8)] |
|
498 + stp d0, d1, [sp, #(0*8)] |
|
499 + stp d2, d3, [sp, #(2*8)] |
|
500 + stp d4, d5, [sp, #(4*8)] |
|
501 + stp d6, d7, [sp, #(6*8)] |
|
502 + |
|
503 + # methodIndex passed from stub |
|
504 + mov w1, w17 |
|
505 + |
|
506 + add x2, sp, #16+(8*(NGPREGS+NFPREGS)) |
|
507 + add x3, sp, #8*NFPREGS |
|
508 + add x4, sp, #0 |
|
509 + |
|
510 + bl PrepareAndDispatch |
|
511 + |
|
512 + add sp, sp, #8*(NGPREGS+NFPREGS) |
|
513 + ldp x29, x30, [sp],#16 |
|
514 + ret |
|
515 + |
|
516 + .size SharedStub, . - SharedStub |
|
517 |