Commit | Line | Data |
---|---|---|
2995be77 SS |
1 | From a44154f7a18496cc3e5fc0b1b2ea69523ebc623a Mon Sep 17 00:00:00 2001 |
2 | From: Simon South <simon@simonsouth.net> | |
3 | Date: Mon, 1 Jun 2020 07:09:34 -0400 | |
4 | Subject: [PATCH] Add support for aarch64 on GNU/Linux | |
5 | ||
6 | --- | |
7 | AUTHORS | 1 + | |
8 | README | 2 +- | |
9 | configure.ac | 7 +- | |
10 | src/arch/Makefile.am | 2 +- | |
11 | src/arch/aarch64.h | 147 +++++++++++++++++++++ | |
12 | src/jam.c | 3 +- | |
13 | src/os/linux/Makefile.am | 2 +- | |
14 | src/os/linux/aarch64/Makefile.am | 28 ++++ | |
15 | src/os/linux/aarch64/callNative.S | 212 ++++++++++++++++++++++++++++++ | |
16 | src/os/linux/aarch64/dll_md.c | 59 +++++++++ | |
17 | src/os/linux/aarch64/init.c | 51 +++++++ | |
18 | 11 files changed, 508 insertions(+), 6 deletions(-) | |
19 | create mode 100644 src/arch/aarch64.h | |
20 | create mode 100644 src/os/linux/aarch64/Makefile.am | |
21 | create mode 100644 src/os/linux/aarch64/callNative.S | |
22 | create mode 100644 src/os/linux/aarch64/dll_md.c | |
23 | create mode 100644 src/os/linux/aarch64/init.c | |
24 | ||
25 | diff --git a/AUTHORS b/AUTHORS | |
26 | index e1334fe..6fd0eeb 100644 | |
27 | --- a/AUTHORS | |
28 | +++ b/AUTHORS | |
29 | @@ -1 +1,2 @@ | |
30 | Robert Lougher <rob@jamvm.org.uk> | |
31 | +Simon South <simon@simonsouth.net> | |
32 | diff --git a/README b/README | |
33 | index c9d80bb..0e93d00 100644 | |
34 | --- a/README | |
35 | +++ b/README | |
36 | @@ -77,7 +77,7 @@ versions of JamVM also includes stubs for common method signatures. | |
37 | The following platforms/architectures are recognised by configure. Those | |
38 | marked with * must be configured to use libffi. | |
39 | ||
40 | -- Linux: x86, x86_64, ARM, PowerPC, PowerPC64(*), MIPS, HPPA | |
41 | +- Linux: x86, x86_64, ARM, ARM64, PowerPC, PowerPC64(*), MIPS, HPPA | |
42 | - FreeBSD: x86, x86_64, ARM, PowerPC, PowerPC64(*), SPARC(*) | |
43 | - OpenBSD: x86, x86_64, ARM, PowerPC, PowerPC64(*), SPARC(*) | |
44 | - Mac OS X/Darwin: x86, x86_64, ARM, PowerPC, PowerPC64 | |
45 | diff --git a/configure.ac b/configure.ac | |
46 | index 138b7e6..e7051d7 100644 | |
47 | --- a/configure.ac | |
48 | +++ b/configure.ac | |
49 | @@ -46,6 +46,7 @@ x86_64-*-freebsd*) host_os=bsd libdl_needed=no ;; | |
50 | arm*-*-linux*) host_cpu=arm host_os=linux interp_cflags=-marm ;; | |
51 | arm*-*-openbsd*) host_cpu=arm host_os=bsd libdl_needed=no ;; | |
52 | arm*-*-freebsd*) host_cpu=arm host_os=bsd libdl_needed=no ;; | |
53 | +aarch64*-*-linux*) host_cpu=aarch64 host_os=linux ;; | |
54 | powerpc*-*-linux*) host_cpu=powerpc host_os=linux ;; | |
55 | powerpc*-*-openbsd*) host_cpu=powerpc host_os=bsd libdl_needed=no ;; | |
56 | powerpc*-*-freebsd*) host_cpu=powerpc host_os=bsd libdl_needed=no ;; | |
57 | @@ -155,10 +156,11 @@ AC_ARG_ENABLE(runtime-reloc-checks, | |
58 | ||
59 | AC_ARG_ENABLE(int-inlining, | |
60 | [AS_HELP_STRING(--enable-int-inlining,enable inline threaded version of the interpreter | |
61 | - (by default enabled on x86_64, i386, powerpc, mips and arm, | |
62 | + (by default enabled on x86_64, i386, powerpc, mips, arm and aarch64, | |
63 | disabled otherwise))],, | |
64 | [if test "$host_cpu" = x86_64 -o "$host_cpu" = i386 -o "$host_cpu" = x86 -o \ | |
65 | - "$host_cpu" = powerpc -o "$host_cpu" = arm -o "$host_cpu" = mips; then | |
66 | + "$host_cpu" = powerpc -o "$host_cpu" = arm -o "$host_cpu" = mips -o \ | |
67 | + "$host_cpu" = aarch64; then | |
68 | enable_int_inlining=yes | |
69 | else | |
70 | enable_int_inlining=no | |
71 | @@ -407,6 +409,7 @@ AC_CONFIG_FILES( | |
72 | src/os/linux/x86_64/Makefile \ | |
73 | src/os/linux/parisc/Makefile \ | |
74 | src/os/linux/mips/Makefile \ | |
75 | + src/os/linux/aarch64/Makefile \ | |
76 | src/os/darwin/i386/Makefile \ | |
77 | src/os/darwin/arm/Makefile \ | |
78 | src/os/darwin/powerpc/Makefile \ | |
79 | diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am | |
80 | index 7580a1b..4e2a4f9 100644 | |
81 | --- a/src/arch/Makefile.am | |
82 | +++ b/src/arch/Makefile.am | |
83 | @@ -19,4 +19,4 @@ | |
84 | ## Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
85 | ## | |
86 | ||
87 | -EXTRA_DIST = powerpc.h arm.h i386.h x86_64.h parisc.h mips.h sparc.h | |
88 | +EXTRA_DIST = powerpc.h arm.h i386.h x86_64.h parisc.h mips.h sparc.h aarch64.h | |
89 | diff --git a/src/arch/aarch64.h b/src/arch/aarch64.h | |
90 | new file mode 100644 | |
91 | index 0000000..1912e79 | |
92 | --- /dev/null | |
93 | +++ b/src/arch/aarch64.h | |
94 | @@ -0,0 +1,147 @@ | |
95 | +/* | |
96 | + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008 | |
97 | + * Robert Lougher <rob@jamvm.org.uk>. | |
98 | + * Copyright (C) 2020 Simon South <simon@simonsouth.net>. | |
99 | + * | |
100 | + * This file is part of JamVM. | |
101 | + * | |
102 | + * This program is free software; you can redistribute it and/or | |
103 | + * modify it under the terms of the GNU General Public License | |
104 | + * as published by the Free Software Foundation; either version 2, | |
105 | + * or (at your option) any later version. | |
106 | + * | |
107 | + * This program is distributed in the hope that it will be useful, | |
108 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
109 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
110 | + * GNU General Public License for more details. | |
111 | + * | |
112 | + * You should have received a copy of the GNU General Public License | |
113 | + * along with this program; if not, write to the Free Software | |
114 | + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
115 | + */ | |
116 | + | |
117 | +#include <stdint.h> | |
118 | + | |
119 | +#define OS_ARCH "aarch64" | |
120 | + | |
121 | +#define HANDLER_TABLE_T static const void | |
122 | +#define DOUBLE_1_BITS 0x3ff0000000000000LL | |
123 | + | |
124 | +#define READ_DBL(v,p,l) v = ((u8)p[0]<<56)|((u8)p[1]<<48)|((u8)p[2]<<40) \ | |
125 | + |((u8)p[3]<<32)|((u8)p[4]<<24)|((u8)p[5]<<16) \ | |
126 | + |((u8)p[6]<<8)|(u8)p[7]; p+=8 | |
127 | + | |
128 | +/* Needed for i386 -- empty here */ | |
129 | +#define FPU_HACK | |
130 | + | |
131 | +#define COMPARE_AND_SWAP_64(addr, old_val, new_val) \ | |
132 | +({ \ | |
133 | + int result, read_val; \ | |
134 | + __asm__ __volatile__ (" \ | |
135 | + 1: ldaxr %2, %1; \ | |
136 | + cmp %2, %3; \ | |
137 | + b.ne 2f; \ | |
138 | + stlxr %w0, %4, %1; \ | |
139 | + cmp %w0, wzr; \ | |
140 | + b.ne 1b; \ | |
141 | + 2: cset %w0, eq;" \ | |
142 | + : "=&r" (result), "+Q" (*addr), "=&r" (read_val) \ | |
143 | + : "r" (old_val), "r" (new_val) \ | |
144 | + : "cc"); \ | |
145 | + result; \ | |
146 | +}) | |
147 | + | |
148 | +#define COMPARE_AND_SWAP_32(addr, old_val, new_val) \ | |
149 | +({ \ | |
150 | + int result, read_val; \ | |
151 | + __asm__ __volatile__ (" \ | |
152 | + 1: ldaxr %w2, %1; \ | |
153 | + cmp %w2, %w3; \ | |
154 | + b.ne 2f; \ | |
155 | + stlxr %w0, %w4, %1; \ | |
156 | + cmp %w0, wzr; \ | |
157 | + b.ne 1b; \ | |
158 | + 2: cset %w0, eq;" \ | |
159 | + : "=&r" (result), "+Q" (*addr), "=&r" (read_val) \ | |
160 | + : "r" (old_val), "r" (new_val) \ | |
161 | + : "cc"); \ | |
162 | + result; \ | |
163 | +}) | |
164 | + | |
165 | +#define COMPARE_AND_SWAP(addr, old_val, new_val) \ | |
166 | + COMPARE_AND_SWAP_64(addr, old_val, new_val) | |
167 | + | |
168 | +#define LOCKWORD_READ(addr) \ | |
169 | +({ \ | |
170 | + uintptr_t result; \ | |
171 | + __asm__ __volatile__ (" \ | |
172 | + ldar %0, %1;" \ | |
173 | + : "=r" (result) \ | |
174 | + : "Q" (*addr) \ | |
175 | + : "cc"); \ | |
176 | + result; \ | |
177 | +}) | |
178 | + | |
179 | +#define LOCKWORD_WRITE(addr, value) \ | |
180 | +({ \ | |
181 | + __asm__ __volatile__ (" \ | |
182 | + stlr %1, %0;" \ | |
183 | + : "=Q" (*addr) \ | |
184 | + : "r" (value) \ | |
185 | + : "cc"); \ | |
186 | +}) | |
187 | + | |
188 | +#define LOCKWORD_COMPARE_AND_SWAP(addr, old_val, new_val) \ | |
189 | + COMPARE_AND_SWAP_64(addr, old_val, new_val) | |
190 | + | |
191 | +#define FLUSH_CACHE(addr, length) \ | |
192 | +{ \ | |
193 | + uintptr_t start = (uintptr_t) (addr); \ | |
194 | + uintptr_t end = start + length; \ | |
195 | + uintptr_t i; \ | |
196 | + \ | |
197 | + for(i = start & aarch64_data_cache_line_mask; \ | |
198 | + i < end; \ | |
199 | + i += aarch64_data_cache_line_len) \ | |
200 | + __asm__ ("dc cvau, %0" :: "r" (i)); \ | |
201 | + \ | |
202 | + __asm__ ("dsb ish"); \ | |
203 | + \ | |
204 | + for(i = start & aarch64_instruction_cache_line_mask; \ | |
205 | + i < end; \ | |
206 | + i += aarch64_instruction_cache_line_len) \ | |
207 | + __asm__ ("ic ivau, %0" :: "r" (i)); \ | |
208 | + \ | |
209 | + __asm__ ("dsb ish; isb"); \ | |
210 | +} | |
211 | + | |
212 | +#define GEN_REL_JMP(target_addr, patch_addr, patch_size) \ | |
213 | +({ \ | |
214 | + int patched = FALSE; \ | |
215 | + \ | |
216 | + if(patch_size >= 4) { \ | |
217 | + /* Guard against the pointer difference being \ | |
218 | + larger than the signed range */ \ | |
219 | + long long offset = (uintptr_t)(target_addr) - \ | |
220 | + (uintptr_t)(patch_addr); \ | |
221 | + \ | |
222 | + if(offset >= -1<<28 && offset < 1<<28) { \ | |
223 | + *(uint32_t*)(patch_addr) = offset>>2 & 0x03ffffff \ | |
224 | + | 0x14000000; \ | |
225 | + patched = TRUE; \ | |
226 | + } \ | |
227 | + } \ | |
228 | + patched; \ | |
229 | +}) | |
230 | + | |
231 | +#define MBARRIER() __asm__ ("dmb ish" ::: "memory") | |
232 | +#define RMBARRIER() __asm__ ("dmb ishld" ::: "memory") | |
233 | +#define WMBARRIER() __asm__ ("dmb ishst" ::: "memory") | |
234 | +#define JMM_LOCK_MBARRIER() __asm__ ("dmb ish" ::: "memory") | |
235 | +#define JMM_UNLOCK_MBARRIER() JMM_LOCK_MBARRIER() | |
236 | + | |
237 | +/* Defined in src/os/linux/aarch64/init.c */ | |
238 | +extern unsigned char aarch64_data_cache_line_len; | |
239 | +extern uintptr_t aarch64_data_cache_line_mask; | |
240 | +extern unsigned char aarch64_instruction_cache_line_len; | |
241 | +extern uintptr_t aarch64_instruction_cache_line_mask; | |
242 | diff --git a/src/jam.c b/src/jam.c | |
243 | index 052f84a..c97524a 100644 | |
244 | --- a/src/jam.c | |
245 | +++ b/src/jam.c | |
246 | @@ -98,7 +98,8 @@ void showUsage(char *name) { | |
247 | void showVersionAndCopyright() { | |
248 | printf("java version \"%s\"\n", JAVA_COMPAT_VERSION); | |
249 | printf("JamVM version %s\n", VERSION); | |
250 | - printf("Copyright (C) 2003-2014 Robert Lougher <rob@jamvm.org.uk>\n\n"); | |
251 | + printf("Copyright (C) 2003-2014 Robert Lougher <rob@jamvm.org.uk>\n"); | |
252 | + printf("Portions Copyright (C) 2020 Simon South <simon@simonsouth.net>\n\n"); | |
253 | printf("This program is free software; you can redistribute it and/or\n"); | |
254 | printf("modify it under the terms of the GNU General Public License\n"); | |
255 | printf("as published by the Free Software Foundation; either version 2,\n"); | |
256 | diff --git a/src/os/linux/Makefile.am b/src/os/linux/Makefile.am | |
257 | index 542094e..83e7dfe 100644 | |
258 | --- a/src/os/linux/Makefile.am | |
259 | +++ b/src/os/linux/Makefile.am | |
260 | @@ -20,7 +20,7 @@ | |
261 | ## | |
262 | ||
263 | SUBDIRS = @arch@ | |
264 | -DIST_SUBDIRS = powerpc arm i386 x86_64 parisc mips | |
265 | +DIST_SUBDIRS = powerpc arm i386 x86_64 parisc mips aarch64 | |
266 | ||
267 | noinst_LTLIBRARIES = libos.la | |
268 | libos_la_SOURCES = os.c | |
269 | diff --git a/src/os/linux/aarch64/Makefile.am b/src/os/linux/aarch64/Makefile.am | |
270 | new file mode 100644 | |
271 | index 0000000..0e5134f | |
272 | --- /dev/null | |
273 | +++ b/src/os/linux/aarch64/Makefile.am | |
274 | @@ -0,0 +1,28 @@ | |
275 | +## | |
276 | +## Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012 | |
277 | +## Robert Lougher <rob@jamvm.org.uk>. | |
278 | +## | |
279 | +## File added by Simon South <simon@simonsouth.net>. | |
280 | +## | |
281 | +## This file is part of JamVM. | |
282 | +## | |
283 | +## This program is free software; you can redistribute it and/or | |
284 | +## modify it under the terms of the GNU General Public License | |
285 | +## as published by the Free Software Foundation; either version 2, | |
286 | +## or (at your option) any later version. | |
287 | +## | |
288 | +## This program is distributed in the hope that it will be useful, | |
289 | +## but WITHOUT ANY WARRANTY; without even the implied warranty of | |
290 | +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
291 | +## GNU General Public License for more details. | |
292 | +## | |
293 | +## You should have received a copy of the GNU General Public License | |
294 | +## along with this program; if not, write to the Free Software | |
295 | +## Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
296 | +## | |
297 | + | |
298 | +noinst_LTLIBRARIES = libnative.la | |
299 | +libnative_la_SOURCES = init.c dll_md.c callNative.S | |
300 | + | |
301 | +AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src | |
302 | +AM_CCASFLAGS = -I$(top_builddir)/src | |
303 | diff --git a/src/os/linux/aarch64/callNative.S b/src/os/linux/aarch64/callNative.S | |
304 | new file mode 100644 | |
305 | index 0000000..e067c4f | |
306 | --- /dev/null | |
307 | +++ b/src/os/linux/aarch64/callNative.S | |
308 | @@ -0,0 +1,212 @@ | |
309 | +/* | |
310 | + * Copyright (C) 2008, 2009, 2011, 2012 Robert Lougher <rob@jamvm.org.uk>. | |
311 | + * Copyright (C) 2020 Simon South <simon@simonsouth.net>. | |
312 | + * | |
313 | + * This file is part of JamVM. | |
314 | + * | |
315 | + * This program is free software; you can redistribute it and/or | |
316 | + * modify it under the terms of the GNU General Public License | |
317 | + * as published by the Free Software Foundation; either version 2, | |
318 | + * or (at your option) any later version. | |
319 | + * | |
320 | + * This program is distributed in the hope that it will be useful, | |
321 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
322 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
323 | + * GNU General Public License for more details. | |
324 | + * | |
325 | + * You should have received a copy of the GNU General Public License | |
326 | + * along with this program; if not, write to the Free Software | |
327 | + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
328 | + */ | |
329 | + | |
330 | +#include "config.h" | |
331 | + | |
332 | +#ifndef USE_FFI | |
333 | + .text | |
334 | + .arch armv8-a | |
335 | + .align 2 | |
336 | + .global callJNIMethod | |
337 | + .type callJNIMethod,function | |
338 | + | |
339 | +/* | |
340 | + * Arguments passed in: | |
341 | + * | |
342 | + * x0 JNIEnv | |
343 | + * x1 class or NULL | |
344 | + * x2 sig | |
345 | + * w3 extra arg | |
346 | + * x4 ostack | |
347 | + * x5 function pntr | |
348 | + * w6 args count | |
349 | + */ | |
350 | + | |
351 | +/* Register usage: | |
352 | + * | |
353 | + * x20 ostack | |
354 | + * x19 sig pntr | |
355 | + * x16 function pntr | |
356 | + * x15 ostack pntr | |
357 | + * x14 args pntr | |
358 | + * x13 float/double handler | |
359 | + * x12 int/long handler | |
360 | + * w11 fp regs remaining | |
361 | + * w10 int regs remaining | |
362 | + * x9 scratch | |
363 | + * x2-x7 outgoing int args | |
364 | + * x1 outgoing class or this pntr | |
365 | + * x0 outgoing JNIEnv (as passed in) | |
366 | + * | |
367 | + * d0 - d7 outgoing float args | |
368 | + */ | |
369 | + | |
370 | +callJNIMethod: | |
371 | + stp x29, x30, [sp, #-32]! | |
372 | + mov x29, sp | |
373 | + stp x19, x20, [x29, #16] | |
374 | + | |
375 | + sub sp, sp, w3 /* allocate room for stacked args */ | |
376 | + mov x14, sp | |
377 | + | |
378 | + mov x20, x4 /* preserve ostack */ | |
379 | + add x19, x2, #1 /* init sig pntr -- skipping '(' */ | |
380 | + | |
381 | + mov x16, x5 /* save function pntr */ | |
382 | + mov x15, x20 /* init ostack pntr */ | |
383 | + | |
384 | + adr x13, fp_reg_handlers-8 | |
385 | + adr x12, int_reg_handlers-8 | |
386 | + | |
387 | + mov w11, #8 /* fp regs remaining */ | |
388 | + mov w10, #6 /* int regs remaining */ | |
389 | + | |
390 | + cbnz x1, scan_sig /* is method non-static? */ | |
391 | + ldr x1, [x15], #8 /* yes, load x1 with "this" */ | |
392 | + | |
393 | +scan_sig: | |
394 | + ldrb w9, [x19], #1 /* get next sig char */ | |
395 | + | |
396 | + cmp w9, #41 /* ')' */ | |
397 | + b.eq done | |
398 | + | |
399 | + cmp w9, #74 /* 'J' */ | |
400 | + b.eq long | |
401 | + | |
402 | + cmp w9, #70 /* 'F' */ | |
403 | + b.eq float | |
404 | + | |
405 | + cmp w9, #68 /* 'D' */ | |
406 | + b.eq double | |
407 | + | |
408 | +skip_brackets: | |
409 | + cmp w9, #91 /* '[' */ | |
410 | + b.ne 1f | |
411 | + ldrb w9, [x19], #1 | |
412 | + b skip_brackets | |
413 | +1: | |
414 | + cmp w9, #76 /* 'L' */ | |
415 | + b.ne int | |
416 | + | |
417 | +skip_ref: | |
418 | + ldrb w9, [x19], #1 | |
419 | + cmp w9, #59 /* ';' */ | |
420 | + b.ne skip_ref | |
421 | + | |
422 | +int: | |
423 | + ldr x9, [x15], #8 | |
424 | + cbz w10, stack_push | |
425 | + | |
426 | +load_int_reg: | |
427 | + sub w10, w10, #1 | |
428 | + add x12, x12, #8 | |
429 | + br x12 | |
430 | + | |
431 | +int_reg_handlers: | |
432 | + mov x2, x9 | |
433 | + b scan_sig | |
434 | + mov x3, x9 | |
435 | + b scan_sig | |
436 | + mov x4, x9 | |
437 | + b scan_sig | |
438 | + mov x5, x9 | |
439 | + b scan_sig | |
440 | + mov x6, x9 | |
441 | + b scan_sig | |
442 | + mov x7, x9 | |
443 | + b scan_sig | |
444 | + | |
445 | +long: | |
446 | + ldr x9, [x15], #16 | |
447 | + cbz w10, stack_push | |
448 | + b load_int_reg | |
449 | + | |
450 | +float: | |
451 | + ldr w9, [x15], #8 | |
452 | + cbz w11, stack_push | |
453 | + b load_fp_reg | |
454 | + | |
455 | +double: | |
456 | + ldr x9, [x15], #16 | |
457 | + cbz w11, stack_push | |
458 | + | |
459 | +load_fp_reg: | |
460 | + sub w11, w11, #1 | |
461 | + add x13, x13, #8 | |
462 | + br x13 | |
463 | + | |
464 | +fp_reg_handlers: | |
465 | + fmov d0, x9 | |
466 | + b scan_sig | |
467 | + fmov d1, x9 | |
468 | + b scan_sig | |
469 | + fmov d2, x9 | |
470 | + b scan_sig | |
471 | + fmov d3, x9 | |
472 | + b scan_sig | |
473 | + fmov d4, x9 | |
474 | + b scan_sig | |
475 | + fmov d5, x9 | |
476 | + b scan_sig | |
477 | + fmov d6, x9 | |
478 | + b scan_sig | |
479 | + fmov d7, x9 | |
480 | + b scan_sig | |
481 | + | |
482 | +stack_push: | |
483 | + str x9, [x14], #8 | |
484 | + b scan_sig | |
485 | + | |
486 | +done: | |
487 | + /* Call the function */ | |
488 | + blr x16 | |
489 | + | |
490 | + mov sp, x29 /* Pop argument area */ | |
491 | + | |
492 | + ldrb w9, [x19] /* Return type */ | |
493 | + | |
494 | + cmp w9, #86 /* 'V' */ | |
495 | + b.eq return | |
496 | + | |
497 | + cmp w9, #68 /* 'D' */ | |
498 | + b.ne 2f | |
499 | + str d0, [x20], #16 | |
500 | + b return | |
501 | +2: | |
502 | + cmp w9, #70 /* 'F' */ | |
503 | + b.ne 3f | |
504 | + str s0, [x20], #8 | |
505 | + b return | |
506 | +3: | |
507 | + cmp w9, #74 /* 'J' */ | |
508 | + b.ne 4f | |
509 | + str x0, [x20], #16 | |
510 | + b return | |
511 | +4: | |
512 | + str x0, [x20], #8 | |
513 | + | |
514 | +return: | |
515 | + mov x0, x20 /* return ostack */ | |
516 | + | |
517 | + ldp x19, x20, [x29, #16] | |
518 | + ldp x29, x30, [sp], #32 | |
519 | + ret | |
520 | +#endif | |
521 | diff --git a/src/os/linux/aarch64/dll_md.c b/src/os/linux/aarch64/dll_md.c | |
522 | new file mode 100644 | |
523 | index 0000000..189f8a8 | |
524 | --- /dev/null | |
525 | +++ b/src/os/linux/aarch64/dll_md.c | |
526 | @@ -0,0 +1,59 @@ | |
527 | +/* | |
528 | + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011 | |
529 | + * Robert Lougher <rob@jamvm.org.uk>. | |
530 | + * Copyright (C) 2020 Simon South <simon@simonsouth.net>. | |
531 | + * | |
532 | + * This file is part of JamVM. | |
533 | + * | |
534 | + * This program is free software; you can redistribute it and/or | |
535 | + * modify it under the terms of the GNU General Public License | |
536 | + * as published by the Free Software Foundation; either version 2, | |
537 | + * or (at your option) any later version. | |
538 | + * | |
539 | + * This program is distributed in the hope that it will be useful, | |
540 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
541 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
542 | + * GNU General Public License for more details. | |
543 | + * | |
544 | + * You should have received a copy of the GNU General Public License | |
545 | + * along with this program; if not, write to the Free Software | |
546 | + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
547 | + */ | |
548 | + | |
549 | +#include "jam.h" | |
550 | + | |
551 | +#ifndef USE_FFI | |
552 | + | |
553 | +int nativeExtraArg(MethodBlock *mb) { | |
554 | + char *sig = mb->type; | |
555 | + int stack_args = 0; | |
556 | + int int_args = 6; | |
557 | + int fp_args = 8; | |
558 | + | |
559 | + while(*++sig != ')') | |
560 | + switch(*sig) { | |
561 | + case 'F': | |
562 | + case 'D': | |
563 | + if(fp_args == 0) | |
564 | + stack_args += 8; | |
565 | + else | |
566 | + fp_args--; | |
567 | + | |
568 | + default: | |
569 | + if(int_args == 0) | |
570 | + stack_args += 8; | |
571 | + else | |
572 | + int_args--; | |
573 | + | |
574 | + if(*sig == '[') | |
575 | + while(*++sig == '['); | |
576 | + if(*sig == 'L') | |
577 | + while(*++sig != ';'); | |
578 | + break; | |
579 | + } | |
580 | + | |
581 | + /* Ensure the stack remains 16 byte aligned. */ | |
582 | + return (stack_args + 15) & ~15; | |
583 | +} | |
584 | + | |
585 | +#endif | |
586 | diff --git a/src/os/linux/aarch64/init.c b/src/os/linux/aarch64/init.c | |
587 | new file mode 100644 | |
588 | index 0000000..b21dc55 | |
589 | --- /dev/null | |
590 | +++ b/src/os/linux/aarch64/init.c | |
591 | @@ -0,0 +1,51 @@ | |
592 | +/* | |
593 | + * Copyright (C) 2003, 2004, 2005, 2006, 2007 | |
594 | + * Robert Lougher <rob@jamvm.org.uk>. | |
595 | + * Copyright (C) 2020 Simon South <simon@simonsouth.net>. | |
596 | + * | |
597 | + * This file is part of JamVM. | |
598 | + * | |
599 | + * This program is free software; you can redistribute it and/or | |
600 | + * modify it under the terms of the GNU General Public License | |
601 | + * as published by the Free Software Foundation; either version 2, | |
602 | + * or (at your option) any later version. | |
603 | + * | |
604 | + * This program is distributed in the hope that it will be useful, | |
605 | + * but WITHOUT ANY WARRANTY; without even the implied warranty of | |
606 | + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
607 | + * GNU General Public License for more details. | |
608 | + * | |
609 | + * You should have received a copy of the GNU General Public License | |
610 | + * along with this program; if not, write to the Free Software | |
611 | + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | |
612 | + */ | |
613 | + | |
614 | +#include "arch/aarch64.h" | |
615 | + | |
616 | +/* Length in bytes of the smallest line in the host system's data cache */ | |
617 | +unsigned char aarch64_data_cache_line_len; | |
618 | + | |
619 | +/* Mask used to align a virtual address to a line in the data cache */ | |
620 | +uintptr_t aarch64_data_cache_line_mask; | |
621 | + | |
622 | +/* Length in bytes of the smallest line in the host system's instruction | |
623 | + cache */ | |
624 | +unsigned char aarch64_instruction_cache_line_len; | |
625 | + | |
626 | +/* Mask used to align a virtual address to a line in the instruction cache */ | |
627 | +uintptr_t aarch64_instruction_cache_line_mask; | |
628 | + | |
629 | +void initialisePlatform() { | |
630 | + unsigned int cache_type; | |
631 | + | |
632 | + /* Extract information from the cache-type register, which describes aspects | |
633 | + of the host's cache configuration */ | |
634 | + __asm__ ("mrs %0, ctr_el0" : "=r" (cache_type)); | |
635 | + | |
636 | + aarch64_data_cache_line_len = 4 << ((cache_type >> 16) & 0x0f); | |
637 | + aarch64_data_cache_line_mask = ~(aarch64_data_cache_line_len - 1); | |
638 | + | |
639 | + aarch64_instruction_cache_line_len = 4 << (cache_type & 0x0f); | |
640 | + aarch64_instruction_cache_line_mask = | |
641 | + ~(aarch64_instruction_cache_line_len - 1); | |
642 | +} | |
643 | -- | |
644 | 2.26.2 | |
645 |