* gnu/packages/java.scm (classpath-devel)[source]: Add (existing) patch. (jamvm)[source]: Add patches. [arguments]: Inherit non-overridden arguments (particularly #:phases) from jamvm-1-bootstrap. * gnu/packages/patches/jamvm-2.0.0-aarch64-support.patch: New file. * gnu/packages/patches/jamvm-2.0.0-opcode-guard.patch: New file. * gnu/local.mk (dist_patch_DATA): Add files. Signed-off-by: Efraim Flashner <efraim@flashner.co.il>
		
			
				
	
	
		
			645 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
			
		
		
	
	
			645 lines
		
	
	
	
		
			23 KiB
		
	
	
	
		
			Diff
		
	
	
	
	
	
| From a44154f7a18496cc3e5fc0b1b2ea69523ebc623a Mon Sep 17 00:00:00 2001
 | |
| From: Simon South <simon@simonsouth.net>
 | |
| Date: Mon, 1 Jun 2020 07:09:34 -0400
 | |
| Subject: [PATCH] Add support for aarch64 on GNU/Linux
 | |
| 
 | |
| ---
 | |
|  AUTHORS                           |   1 +
 | |
|  README                            |   2 +-
 | |
|  configure.ac                      |   7 +-
 | |
|  src/arch/Makefile.am              |   2 +-
 | |
|  src/arch/aarch64.h                | 147 +++++++++++++++++++++
 | |
|  src/jam.c                         |   3 +-
 | |
|  src/os/linux/Makefile.am          |   2 +-
 | |
|  src/os/linux/aarch64/Makefile.am  |  28 ++++
 | |
|  src/os/linux/aarch64/callNative.S | 212 ++++++++++++++++++++++++++++++
 | |
|  src/os/linux/aarch64/dll_md.c     |  59 +++++++++
 | |
|  src/os/linux/aarch64/init.c       |  51 +++++++
 | |
|  11 files changed, 508 insertions(+), 6 deletions(-)
 | |
|  create mode 100644 src/arch/aarch64.h
 | |
|  create mode 100644 src/os/linux/aarch64/Makefile.am
 | |
|  create mode 100644 src/os/linux/aarch64/callNative.S
 | |
|  create mode 100644 src/os/linux/aarch64/dll_md.c
 | |
|  create mode 100644 src/os/linux/aarch64/init.c
 | |
| 
 | |
| diff --git a/AUTHORS b/AUTHORS
 | |
| index e1334fe..6fd0eeb 100644
 | |
| --- a/AUTHORS
 | |
| +++ b/AUTHORS
 | |
| @@ -1 +1,2 @@
 | |
|  Robert Lougher <rob@jamvm.org.uk>
 | |
| +Simon South <simon@simonsouth.net>
 | |
| diff --git a/README b/README
 | |
| index c9d80bb..0e93d00 100644
 | |
| --- a/README
 | |
| +++ b/README
 | |
| @@ -77,7 +77,7 @@ versions of JamVM also includes stubs for common method signatures.
 | |
|  The following platforms/architectures are recognised by configure.  Those
 | |
|  marked with * must be configured to use libffi.
 | |
|  
 | |
| -- Linux: x86, x86_64, ARM, PowerPC, PowerPC64(*), MIPS, HPPA
 | |
| +- Linux: x86, x86_64, ARM, ARM64, PowerPC, PowerPC64(*), MIPS, HPPA
 | |
|  - FreeBSD: x86, x86_64, ARM, PowerPC, PowerPC64(*), SPARC(*)
 | |
|  - OpenBSD: x86, x86_64, ARM, PowerPC, PowerPC64(*), SPARC(*)
 | |
|  - Mac OS X/Darwin: x86, x86_64, ARM, PowerPC, PowerPC64
 | |
| diff --git a/configure.ac b/configure.ac
 | |
| index 138b7e6..e7051d7 100644
 | |
| --- a/configure.ac
 | |
| +++ b/configure.ac
 | |
| @@ -46,6 +46,7 @@ x86_64-*-freebsd*) host_os=bsd libdl_needed=no ;;
 | |
|  arm*-*-linux*) host_cpu=arm host_os=linux interp_cflags=-marm ;;
 | |
|  arm*-*-openbsd*) host_cpu=arm host_os=bsd libdl_needed=no ;;
 | |
|  arm*-*-freebsd*) host_cpu=arm host_os=bsd libdl_needed=no ;;
 | |
| +aarch64*-*-linux*) host_cpu=aarch64 host_os=linux ;;
 | |
|  powerpc*-*-linux*) host_cpu=powerpc host_os=linux ;;
 | |
|  powerpc*-*-openbsd*) host_cpu=powerpc host_os=bsd libdl_needed=no ;;
 | |
|  powerpc*-*-freebsd*) host_cpu=powerpc host_os=bsd libdl_needed=no ;;
 | |
| @@ -155,10 +156,11 @@ AC_ARG_ENABLE(runtime-reloc-checks,
 | |
|  
 | |
|  AC_ARG_ENABLE(int-inlining,
 | |
|      [AS_HELP_STRING(--enable-int-inlining,enable inline threaded version of the interpreter
 | |
| -                   (by default enabled on x86_64, i386, powerpc, mips and arm, 
 | |
| +                   (by default enabled on x86_64, i386, powerpc, mips, arm and aarch64,
 | |
|                      disabled otherwise))],,
 | |
|      [if test "$host_cpu" = x86_64 -o "$host_cpu" = i386 -o "$host_cpu" = x86 -o \
 | |
| -             "$host_cpu" = powerpc -o "$host_cpu" = arm -o "$host_cpu" = mips; then
 | |
| +             "$host_cpu" = powerpc -o "$host_cpu" = arm -o "$host_cpu" = mips -o \
 | |
| +             "$host_cpu" = aarch64; then
 | |
|           enable_int_inlining=yes
 | |
|         else
 | |
|           enable_int_inlining=no
 | |
| @@ -407,6 +409,7 @@ AC_CONFIG_FILES(
 | |
|      src/os/linux/x86_64/Makefile \
 | |
|      src/os/linux/parisc/Makefile \
 | |
|      src/os/linux/mips/Makefile \
 | |
| +    src/os/linux/aarch64/Makefile \
 | |
|      src/os/darwin/i386/Makefile \
 | |
|      src/os/darwin/arm/Makefile \
 | |
|      src/os/darwin/powerpc/Makefile \
 | |
| diff --git a/src/arch/Makefile.am b/src/arch/Makefile.am
 | |
| index 7580a1b..4e2a4f9 100644
 | |
| --- a/src/arch/Makefile.am
 | |
| +++ b/src/arch/Makefile.am
 | |
| @@ -19,4 +19,4 @@
 | |
|  ## Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | |
|  ##
 | |
|  
 | |
| -EXTRA_DIST = powerpc.h arm.h i386.h x86_64.h parisc.h mips.h sparc.h
 | |
| +EXTRA_DIST = powerpc.h arm.h i386.h x86_64.h parisc.h mips.h sparc.h aarch64.h
 | |
| diff --git a/src/arch/aarch64.h b/src/arch/aarch64.h
 | |
| new file mode 100644
 | |
| index 0000000..1912e79
 | |
| --- /dev/null
 | |
| +++ b/src/arch/aarch64.h
 | |
| @@ -0,0 +1,147 @@
 | |
| +/*
 | |
| + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008
 | |
| + * Robert Lougher <rob@jamvm.org.uk>.
 | |
| + * Copyright (C) 2020 Simon South <simon@simonsouth.net>.
 | |
| + *
 | |
| + * This file is part of JamVM.
 | |
| + *
 | |
| + * This program is free software; you can redistribute it and/or
 | |
| + * modify it under the terms of the GNU General Public License
 | |
| + * as published by the Free Software Foundation; either version 2,
 | |
| + * or (at your option) any later version.
 | |
| + *
 | |
| + * This program is distributed in the hope that it will be useful,
 | |
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| + * GNU General Public License for more details.
 | |
| + *
 | |
| + * You should have received a copy of the GNU General Public License
 | |
| + * along with this program; if not, write to the Free Software
 | |
| + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | |
| + */
 | |
| +
 | |
| +#include <stdint.h>
 | |
| +
 | |
| +#define OS_ARCH "aarch64"
 | |
| +
 | |
| +#define HANDLER_TABLE_T static const void
 | |
| +#define DOUBLE_1_BITS 0x3ff0000000000000LL
 | |
| +
 | |
| +#define READ_DBL(v,p,l) v = ((u8)p[0]<<56)|((u8)p[1]<<48)|((u8)p[2]<<40) \
 | |
| +                            |((u8)p[3]<<32)|((u8)p[4]<<24)|((u8)p[5]<<16) \
 | |
| +                            |((u8)p[6]<<8)|(u8)p[7]; p+=8
 | |
| +
 | |
| +/* Needed for i386 -- empty here */
 | |
| +#define FPU_HACK
 | |
| +
 | |
| +#define COMPARE_AND_SWAP_64(addr, old_val, new_val)             \
 | |
| +({                                                              \
 | |
| +    int result, read_val;                                       \
 | |
| +    __asm__ __volatile__ ("                                     \
 | |
| +        1:      ldaxr %2, %1;                                   \
 | |
| +                cmp %2, %3;                                     \
 | |
| +                b.ne 2f;                                        \
 | |
| +                stlxr %w0, %4, %1;                              \
 | |
| +                cmp %w0, wzr;                                   \
 | |
| +                b.ne 1b;                                        \
 | |
| +        2:      cset %w0, eq;"                                  \
 | |
| +    : "=&r" (result), "+Q" (*addr), "=&r" (read_val)            \
 | |
| +    : "r" (old_val), "r" (new_val)                              \
 | |
| +    : "cc");                                                    \
 | |
| +    result;                                                     \
 | |
| +})
 | |
| +
 | |
| +#define COMPARE_AND_SWAP_32(addr, old_val, new_val)             \
 | |
| +({                                                              \
 | |
| +    int result, read_val;                                       \
 | |
| +    __asm__ __volatile__ ("                                     \
 | |
| +        1:      ldaxr %w2, %1;                                  \
 | |
| +                cmp %w2, %w3;                                   \
 | |
| +                b.ne 2f;                                        \
 | |
| +                stlxr %w0, %w4, %1;                             \
 | |
| +                cmp %w0, wzr;                                   \
 | |
| +                b.ne 1b;                                        \
 | |
| +        2:      cset %w0, eq;"                                  \
 | |
| +    : "=&r" (result), "+Q" (*addr), "=&r" (read_val)            \
 | |
| +    : "r" (old_val), "r" (new_val)                              \
 | |
| +    : "cc");                                                    \
 | |
| +    result;                                                     \
 | |
| +})
 | |
| +
 | |
| +#define COMPARE_AND_SWAP(addr, old_val, new_val)                \
 | |
| +        COMPARE_AND_SWAP_64(addr, old_val, new_val)
 | |
| +
 | |
| +#define LOCKWORD_READ(addr)                                     \
 | |
| +({                                                              \
 | |
| +    uintptr_t result;                                           \
 | |
| +    __asm__ __volatile__ ("                                     \
 | |
| +                ldar %0, %1;"                                   \
 | |
| +    : "=r" (result)                                             \
 | |
| +    : "Q" (*addr)                                               \
 | |
| +    : "cc");                                                    \
 | |
| +    result;                                                     \
 | |
| +})
 | |
| +
 | |
| +#define LOCKWORD_WRITE(addr, value)                             \
 | |
| +({                                                              \
 | |
| +    __asm__ __volatile__ ("                                     \
 | |
| +                stlr %1, %0;"                                   \
 | |
| +    : "=Q" (*addr)                                              \
 | |
| +    : "r" (value)                                               \
 | |
| +    : "cc");                                                    \
 | |
| +})
 | |
| +
 | |
| +#define LOCKWORD_COMPARE_AND_SWAP(addr, old_val, new_val)       \
 | |
| +        COMPARE_AND_SWAP_64(addr, old_val, new_val)
 | |
| +
 | |
| +#define FLUSH_CACHE(addr, length)                               \
 | |
| +{                                                               \
 | |
| +    uintptr_t start = (uintptr_t) (addr);                       \
 | |
| +    uintptr_t end = start + length;                             \
 | |
| +    uintptr_t i;                                                \
 | |
| +                                                                \
 | |
| +    for(i = start & aarch64_data_cache_line_mask;               \
 | |
| +        i < end;                                                \
 | |
| +        i += aarch64_data_cache_line_len)                       \
 | |
| +        __asm__ ("dc cvau, %0" :: "r" (i));                     \
 | |
| +                                                                \
 | |
| +    __asm__ ("dsb ish");                                        \
 | |
| +                                                                \
 | |
| +    for(i = start & aarch64_instruction_cache_line_mask;        \
 | |
| +        i < end;                                                \
 | |
| +        i += aarch64_instruction_cache_line_len)                \
 | |
| +        __asm__ ("ic ivau, %0" :: "r" (i));                     \
 | |
| +                                                                \
 | |
| +    __asm__ ("dsb ish; isb");                                   \
 | |
| +}
 | |
| +
 | |
| +#define GEN_REL_JMP(target_addr, patch_addr, patch_size)        \
 | |
| +({                                                              \
 | |
| +    int patched = FALSE;                                        \
 | |
| +                                                                \
 | |
| +    if(patch_size >= 4) {                                       \
 | |
| +        /* Guard against the pointer difference being           \
 | |
| +           larger than the signed range */                      \
 | |
| +        long long offset = (uintptr_t)(target_addr) -           \
 | |
| +                           (uintptr_t)(patch_addr);             \
 | |
| +                                                                \
 | |
| +        if(offset >= -1<<28 && offset < 1<<28) {                \
 | |
| +            *(uint32_t*)(patch_addr) = offset>>2 & 0x03ffffff   \
 | |
| +                                                 | 0x14000000;  \
 | |
| +            patched = TRUE;                                     \
 | |
| +        }                                                       \
 | |
| +    }                                                           \
 | |
| +    patched;                                                    \
 | |
| +})
 | |
| +
 | |
| +#define MBARRIER() __asm__ ("dmb ish" ::: "memory")
 | |
| +#define RMBARRIER() __asm__ ("dmb ishld" ::: "memory")
 | |
| +#define WMBARRIER() __asm__ ("dmb ishst" ::: "memory")
 | |
| +#define JMM_LOCK_MBARRIER() __asm__ ("dmb ish" ::: "memory")
 | |
| +#define JMM_UNLOCK_MBARRIER() JMM_LOCK_MBARRIER()
 | |
| +
 | |
| +/* Defined in src/os/linux/aarch64/init.c */
 | |
| +extern unsigned char aarch64_data_cache_line_len;
 | |
| +extern uintptr_t aarch64_data_cache_line_mask;
 | |
| +extern unsigned char aarch64_instruction_cache_line_len;
 | |
| +extern uintptr_t aarch64_instruction_cache_line_mask;
 | |
| diff --git a/src/jam.c b/src/jam.c
 | |
| index 052f84a..c97524a 100644
 | |
| --- a/src/jam.c
 | |
| +++ b/src/jam.c
 | |
| @@ -98,7 +98,8 @@ void showUsage(char *name) {
 | |
|  void showVersionAndCopyright() {
 | |
|      printf("java version \"%s\"\n", JAVA_COMPAT_VERSION);
 | |
|      printf("JamVM version %s\n", VERSION);
 | |
| -    printf("Copyright (C) 2003-2014 Robert Lougher <rob@jamvm.org.uk>\n\n");
 | |
| +    printf("Copyright (C) 2003-2014 Robert Lougher <rob@jamvm.org.uk>\n");
 | |
| +    printf("Portions Copyright (C) 2020 Simon South <simon@simonsouth.net>\n\n");
 | |
|      printf("This program is free software; you can redistribute it and/or\n");
 | |
|      printf("modify it under the terms of the GNU General Public License\n");
 | |
|      printf("as published by the Free Software Foundation; either version 2,\n");
 | |
| diff --git a/src/os/linux/Makefile.am b/src/os/linux/Makefile.am
 | |
| index 542094e..83e7dfe 100644
 | |
| --- a/src/os/linux/Makefile.am
 | |
| +++ b/src/os/linux/Makefile.am
 | |
| @@ -20,7 +20,7 @@
 | |
|  ##
 | |
|  
 | |
|  SUBDIRS = @arch@
 | |
| -DIST_SUBDIRS = powerpc arm i386 x86_64 parisc mips
 | |
| +DIST_SUBDIRS = powerpc arm i386 x86_64 parisc mips aarch64
 | |
|  
 | |
|  noinst_LTLIBRARIES = libos.la
 | |
|  libos_la_SOURCES = os.c
 | |
| diff --git a/src/os/linux/aarch64/Makefile.am b/src/os/linux/aarch64/Makefile.am
 | |
| new file mode 100644
 | |
| index 0000000..0e5134f
 | |
| --- /dev/null
 | |
| +++ b/src/os/linux/aarch64/Makefile.am
 | |
| @@ -0,0 +1,28 @@
 | |
| +##
 | |
| +## Copyright (C) 2003, 2004, 2005, 2006, 2007, 2010, 2011, 2012
 | |
| +## Robert Lougher <rob@jamvm.org.uk>.
 | |
| +##
 | |
| +## File added by Simon South <simon@simonsouth.net>.
 | |
| +##
 | |
| +## This file is part of JamVM.
 | |
| +##
 | |
| +## This program is free software; you can redistribute it and/or
 | |
| +## modify it under the terms of the GNU General Public License
 | |
| +## as published by the Free Software Foundation; either version 2,
 | |
| +## or (at your option) any later version.
 | |
| +##
 | |
| +## This program is distributed in the hope that it will be useful,
 | |
| +## but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| +## MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| +## GNU General Public License for more details.
 | |
| +##
 | |
| +## You should have received a copy of the GNU General Public License
 | |
| +## along with this program; if not, write to the Free Software
 | |
| +## Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | |
| +##
 | |
| +
 | |
| +noinst_LTLIBRARIES = libnative.la
 | |
| +libnative_la_SOURCES = init.c dll_md.c callNative.S
 | |
| +
 | |
| +AM_CPPFLAGS = -I$(top_builddir)/src -I$(top_srcdir)/src
 | |
| +AM_CCASFLAGS = -I$(top_builddir)/src
 | |
| diff --git a/src/os/linux/aarch64/callNative.S b/src/os/linux/aarch64/callNative.S
 | |
| new file mode 100644
 | |
| index 0000000..e067c4f
 | |
| --- /dev/null
 | |
| +++ b/src/os/linux/aarch64/callNative.S
 | |
| @@ -0,0 +1,212 @@
 | |
| +/*
 | |
| + * Copyright (C) 2008, 2009, 2011, 2012 Robert Lougher <rob@jamvm.org.uk>.
 | |
| + * Copyright (C) 2020 Simon South <simon@simonsouth.net>.
 | |
| + *
 | |
| + * This file is part of JamVM.
 | |
| + *
 | |
| + * This program is free software; you can redistribute it and/or
 | |
| + * modify it under the terms of the GNU General Public License
 | |
| + * as published by the Free Software Foundation; either version 2,
 | |
| + * or (at your option) any later version.
 | |
| + *
 | |
| + * This program is distributed in the hope that it will be useful,
 | |
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| + * GNU General Public License for more details.
 | |
| + *
 | |
| + * You should have received a copy of the GNU General Public License
 | |
| + * along with this program; if not, write to the Free Software
 | |
| + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | |
| + */
 | |
| +
 | |
| +#include "config.h"
 | |
| +
 | |
| +#ifndef USE_FFI
 | |
| +        .text
 | |
| +        .arch armv8-a
 | |
| +        .align 2
 | |
| +        .global callJNIMethod
 | |
| +        .type callJNIMethod,function
 | |
| +
 | |
| +/*
 | |
| + * Arguments passed in:
 | |
| + *
 | |
| + * x0 JNIEnv
 | |
| + * x1 class or NULL
 | |
| + * x2 sig
 | |
| + * w3 extra arg
 | |
| + * x4 ostack
 | |
| + * x5 function pntr
 | |
| + * w6 args count
 | |
| + */
 | |
| +
 | |
| +/* Register usage:
 | |
| + *
 | |
| + * x20 ostack
 | |
| + * x19 sig pntr
 | |
| + * x16 function pntr
 | |
| + * x15 ostack pntr
 | |
| + * x14 args pntr
 | |
| + * x13 float/double handler
 | |
| + * x12 int/long handler
 | |
| + * w11 fp regs remaining
 | |
| + * w10 int regs remaining
 | |
| + * x9 scratch
 | |
| + * x2-x7 outgoing int args
 | |
| + * x1 outgoing class or this pntr
 | |
| + * x0 outgoing JNIEnv (as passed in)
 | |
| + *
 | |
| + * d0 - d7 outgoing float args
 | |
| + */
 | |
| +
 | |
| +callJNIMethod:
 | |
| +        stp     x29, x30, [sp, #-32]!
 | |
| +        mov     x29, sp
 | |
| +        stp     x19, x20, [x29, #16]
 | |
| +
 | |
| +        sub     sp, sp, w3              /* allocate room for stacked args */
 | |
| +        mov     x14, sp
 | |
| +
 | |
| +        mov     x20, x4                 /* preserve ostack */
 | |
| +        add     x19, x2, #1             /* init sig pntr -- skipping '(' */
 | |
| +
 | |
| +        mov     x16, x5                 /* save function pntr */
 | |
| +        mov     x15, x20                /* init ostack pntr */
 | |
| +
 | |
| +        adr     x13, fp_reg_handlers-8
 | |
| +        adr     x12, int_reg_handlers-8
 | |
| +
 | |
| +        mov     w11, #8                 /* fp regs remaining */
 | |
| +        mov     w10, #6                 /* int regs remaining */
 | |
| +
 | |
| +        cbnz    x1, scan_sig            /* is method non-static? */
 | |
| +        ldr     x1, [x15], #8           /* yes, load x1 with "this" */
 | |
| +
 | |
| +scan_sig:
 | |
| +        ldrb    w9, [x19], #1           /* get next sig char */
 | |
| +
 | |
| +        cmp     w9, #41                 /* ')' */
 | |
| +        b.eq    done
 | |
| +
 | |
| +        cmp     w9, #74                 /* 'J' */
 | |
| +        b.eq    long
 | |
| +
 | |
| +        cmp     w9, #70                 /* 'F' */
 | |
| +        b.eq    float
 | |
| +
 | |
| +        cmp     w9, #68                 /* 'D' */
 | |
| +        b.eq    double
 | |
| +
 | |
| +skip_brackets:
 | |
| +        cmp     w9, #91                 /* '[' */
 | |
| +        b.ne    1f
 | |
| +        ldrb    w9, [x19], #1
 | |
| +        b       skip_brackets
 | |
| +1:
 | |
| +        cmp     w9, #76                 /* 'L' */
 | |
| +        b.ne    int
 | |
| +
 | |
| +skip_ref:
 | |
| +        ldrb    w9, [x19], #1
 | |
| +        cmp     w9, #59                 /* ';' */
 | |
| +        b.ne    skip_ref
 | |
| +
 | |
| +int:
 | |
| +        ldr     x9, [x15], #8
 | |
| +        cbz     w10, stack_push
 | |
| +
 | |
| +load_int_reg:
 | |
| +        sub     w10, w10, #1
 | |
| +        add     x12, x12, #8
 | |
| +        br      x12
 | |
| +
 | |
| +int_reg_handlers:
 | |
| +        mov     x2, x9
 | |
| +        b       scan_sig
 | |
| +        mov     x3, x9
 | |
| +        b       scan_sig
 | |
| +        mov     x4, x9
 | |
| +        b       scan_sig
 | |
| +        mov     x5, x9
 | |
| +        b       scan_sig
 | |
| +        mov     x6, x9
 | |
| +        b       scan_sig
 | |
| +        mov     x7, x9
 | |
| +        b       scan_sig
 | |
| +
 | |
| +long:
 | |
| +        ldr     x9, [x15], #16
 | |
| +        cbz     w10, stack_push
 | |
| +        b       load_int_reg
 | |
| +
 | |
| +float:
 | |
| +        ldr     w9, [x15], #8
 | |
| +        cbz     w11, stack_push
 | |
| +        b       load_fp_reg
 | |
| +
 | |
| +double:
 | |
| +        ldr     x9, [x15], #16
 | |
| +        cbz     w11, stack_push
 | |
| +
 | |
| +load_fp_reg:
 | |
| +        sub     w11, w11, #1
 | |
| +        add     x13, x13, #8
 | |
| +        br      x13
 | |
| +
 | |
| +fp_reg_handlers:
 | |
| +        fmov    d0, x9
 | |
| +        b       scan_sig
 | |
| +        fmov    d1, x9
 | |
| +        b       scan_sig
 | |
| +        fmov    d2, x9
 | |
| +        b       scan_sig
 | |
| +        fmov    d3, x9
 | |
| +        b       scan_sig
 | |
| +        fmov    d4, x9
 | |
| +        b       scan_sig
 | |
| +        fmov    d5, x9
 | |
| +        b       scan_sig
 | |
| +        fmov    d6, x9
 | |
| +        b       scan_sig
 | |
| +        fmov    d7, x9
 | |
| +        b       scan_sig
 | |
| +
 | |
| +stack_push:
 | |
| +        str     x9, [x14], #8
 | |
| +        b       scan_sig
 | |
| +
 | |
| +done:
 | |
| +        /* Call the function */
 | |
| +        blr     x16
 | |
| +
 | |
| +        mov     sp, x29                 /* Pop argument area */
 | |
| +
 | |
| +        ldrb    w9, [x19]               /* Return type */
 | |
| +
 | |
| +        cmp     w9, #86                 /* 'V' */
 | |
| +        b.eq    return
 | |
| +
 | |
| +        cmp     w9, #68                 /* 'D' */
 | |
| +        b.ne    2f
 | |
| +        str     d0, [x20], #16
 | |
| +        b       return
 | |
| +2:
 | |
| +        cmp     w9, #70                 /* 'F' */
 | |
| +        b.ne    3f
 | |
| +        str     s0, [x20], #8
 | |
| +        b       return
 | |
| +3:
 | |
| +        cmp     w9, #74                 /* 'J' */
 | |
| +        b.ne    4f
 | |
| +        str     x0, [x20], #16
 | |
| +        b       return
 | |
| +4:
 | |
| +        str     x0, [x20], #8
 | |
| +
 | |
| +return:
 | |
| +        mov     x0, x20                 /* return ostack */
 | |
| +
 | |
| +        ldp     x19, x20, [x29, #16]
 | |
| +        ldp     x29, x30, [sp], #32
 | |
| +        ret
 | |
| +#endif
 | |
| diff --git a/src/os/linux/aarch64/dll_md.c b/src/os/linux/aarch64/dll_md.c
 | |
| new file mode 100644
 | |
| index 0000000..189f8a8
 | |
| --- /dev/null
 | |
| +++ b/src/os/linux/aarch64/dll_md.c
 | |
| @@ -0,0 +1,59 @@
 | |
| +/*
 | |
| + * Copyright (C) 2003, 2004, 2005, 2006, 2007, 2008, 2010, 2011
 | |
| + * Robert Lougher <rob@jamvm.org.uk>.
 | |
| + * Copyright (C) 2020 Simon South <simon@simonsouth.net>.
 | |
| + *
 | |
| + * This file is part of JamVM.
 | |
| + *
 | |
| + * This program is free software; you can redistribute it and/or
 | |
| + * modify it under the terms of the GNU General Public License
 | |
| + * as published by the Free Software Foundation; either version 2,
 | |
| + * or (at your option) any later version.
 | |
| + *
 | |
| + * This program is distributed in the hope that it will be useful,
 | |
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| + * GNU General Public License for more details.
 | |
| + *
 | |
| + * You should have received a copy of the GNU General Public License
 | |
| + * along with this program; if not, write to the Free Software
 | |
| + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | |
| + */
 | |
| +
 | |
| +#include "jam.h"
 | |
| +
 | |
| +#ifndef USE_FFI
 | |
| +
 | |
| +int nativeExtraArg(MethodBlock *mb) {
 | |
| +    char *sig = mb->type;
 | |
| +    int stack_args = 0;
 | |
| +    int int_args = 6;
 | |
| +    int fp_args = 8;
 | |
| +
 | |
| +    while(*++sig != ')')
 | |
| +        switch(*sig) {
 | |
| +        case 'F':
 | |
| +        case 'D':
 | |
| +            if(fp_args == 0)
 | |
| +                stack_args += 8;
 | |
| +            else
 | |
| +                fp_args--;
 | |
| +
 | |
| +        default:
 | |
| +            if(int_args == 0)
 | |
| +                stack_args += 8;
 | |
| +            else
 | |
| +                int_args--;
 | |
| +
 | |
| +            if(*sig == '[')
 | |
| +                while(*++sig == '[');
 | |
| +            if(*sig == 'L')
 | |
| +                while(*++sig != ';');
 | |
| +            break;
 | |
| +        }
 | |
| +
 | |
| +    /* Ensure the stack remains 16 byte aligned. */
 | |
| +    return (stack_args + 15) & ~15;
 | |
| +}
 | |
| +
 | |
| +#endif
 | |
| diff --git a/src/os/linux/aarch64/init.c b/src/os/linux/aarch64/init.c
 | |
| new file mode 100644
 | |
| index 0000000..b21dc55
 | |
| --- /dev/null
 | |
| +++ b/src/os/linux/aarch64/init.c
 | |
| @@ -0,0 +1,51 @@
 | |
| +/*
 | |
| + * Copyright (C) 2003, 2004, 2005, 2006, 2007
 | |
| + * Robert Lougher <rob@jamvm.org.uk>.
 | |
| + * Copyright (C) 2020 Simon South <simon@simonsouth.net>.
 | |
| + *
 | |
| + * This file is part of JamVM.
 | |
| + *
 | |
| + * This program is free software; you can redistribute it and/or
 | |
| + * modify it under the terms of the GNU General Public License
 | |
| + * as published by the Free Software Foundation; either version 2,
 | |
| + * or (at your option) any later version.
 | |
| + *
 | |
| + * This program is distributed in the hope that it will be useful,
 | |
| + * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
| + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | |
| + * GNU General Public License for more details.
 | |
| + *
 | |
| + * You should have received a copy of the GNU General Public License
 | |
| + * along with this program; if not, write to the Free Software
 | |
| + * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
 | |
| + */
 | |
| +
 | |
| +#include "arch/aarch64.h"
 | |
| +
 | |
| +/* Length in bytes of the smallest line in the host system's data cache */
 | |
| +unsigned char aarch64_data_cache_line_len;
 | |
| +
 | |
| +/* Mask used to align a virtual address to a line in the data cache */
 | |
| +uintptr_t aarch64_data_cache_line_mask;
 | |
| +
 | |
| +/* Length in bytes of the smallest line in the host system's instruction
 | |
| +   cache */
 | |
| +unsigned char aarch64_instruction_cache_line_len;
 | |
| +
 | |
| +/* Mask used to align a virtual address to a line in the instruction cache */
 | |
| +uintptr_t aarch64_instruction_cache_line_mask;
 | |
| +
 | |
| +void initialisePlatform() {
 | |
| +    unsigned int cache_type;
 | |
| +
 | |
| +    /* Extract information from the cache-type register, which describes aspects
 | |
| +       of the host's cache configuration */
 | |
| +    __asm__ ("mrs %0, ctr_el0" : "=r" (cache_type));
 | |
| +
 | |
| +    aarch64_data_cache_line_len = 4 << ((cache_type >> 16) & 0x0f);
 | |
| +    aarch64_data_cache_line_mask = ~(aarch64_data_cache_line_len - 1);
 | |
| +
 | |
| +    aarch64_instruction_cache_line_len = 4 << (cache_type & 0x0f);
 | |
| +    aarch64_instruction_cache_line_mask =
 | |
| +        ~(aarch64_instruction_cache_line_len - 1);
 | |
| +}
 | |
| -- 
 | |
| 2.26.2
 | |
| 
 |