715
|
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 |
|