Bläddra i källkod

+ FreeBSD/AArch64 support (patch by Mikaël Urankar, mantis #38441)

git-svn-id: trunk@49157 -
Jonas Maebe 4 år sedan
förälder
incheckning
d8021a1102

+ 9 - 0
.gitattributes

@@ -10422,6 +10422,8 @@ rtl/beos/termiosproc.inc svneol=native#text/plain
 rtl/beos/tthread.inc svneol=native#text/plain
 rtl/beos/unxconst.inc svneol=native#text/plain
 rtl/beos/unxfunc.inc svneol=native#text/plain
+rtl/bsd/aarch64/syscall.inc svneol=native#text/plain
+rtl/bsd/aarch64/syscallh.inc svneol=native#text/plain
 rtl/bsd/bsd.pas -text svneol=unset#text/plain
 rtl/bsd/bunxfunch.inc svneol=native#text/plain
 rtl/bsd/bunxsysc.inc svneol=native#text/plain
@@ -10862,6 +10864,13 @@ rtl/fpmake.inc svneol=native#text/plain
 rtl/fpmake.pp svneol=native#text/plain
 rtl/freebsd/Makefile svneol=native#text/plain
 rtl/freebsd/Makefile.fpc svneol=native#text/plain
+rtl/freebsd/aarch64/bsyscall.inc svneol=native#text/plain
+rtl/freebsd/aarch64/cprt0.as svneol=native#text/plain
+rtl/freebsd/aarch64/dllprt0.as svneol=native#text/plain
+rtl/freebsd/aarch64/gprt0.as svneol=native#text/plain
+rtl/freebsd/aarch64/prt0.as svneol=native#text/plain
+rtl/freebsd/aarch64/si_c.inc svneol=native#text/plain
+rtl/freebsd/aarch64/sighnd.inc svneol=native#text/plain
 rtl/freebsd/buildrtl.lpi svneol=native#text/plain
 rtl/freebsd/buildrtl.pp svneol=native#text/plain
 rtl/freebsd/console.pp svneol=native#text/plain

+ 1 - 1
compiler/aarch64/agcpugas.pas

@@ -774,7 +774,7 @@ unit agcpugas;
             idtxt  : 'AS';
             asmbin : 'as';
             asmcmd : '-o $OBJ $EXTRAOPT $ASM';
-            supported_targets : [system_aarch64_linux,system_aarch64_android];
+            supported_targets : [system_aarch64_freebsd,system_aarch64_linux,system_aarch64_android];
             flags : [af_needar,af_smartlink_sections];
             labelprefix : '.L';
             labelmaxlen : -1;

+ 3 - 0
compiler/aarch64/cputarg.pas

@@ -35,6 +35,9 @@ implementation
              Targets
 **************************************}
 
+    {$ifndef NOTARGETBSD}
+      ,t_bsd
+    {$endif}
     {$ifndef NOTARGETLINUX}
       ,t_linux
     {$endif}

+ 2 - 1
compiler/systems.inc

@@ -203,7 +203,8 @@
              system_aarch64_darwin,     { 111 }
              system_z80_amstradcpc,     { 112 }
              system_m68k_sinclairql,    { 113 }
-             system_wasm32_wasi         { 114 }
+             system_wasm32_wasi,        { 114 }
+             system_aarch64_freebsd     { 115 }
        );
 
      type

+ 7 - 2
compiler/systems.pas

@@ -264,7 +264,8 @@ interface
                        system_x86_6432_linux,system_mipseb_linux,system_mipsel_linux,system_aarch64_linux,
                        system_riscv32_linux,system_riscv64_linux,system_xtensa_linux];
        systems_dragonfly = [system_x86_64_dragonfly];
-       systems_freebsd = [system_i386_freebsd,
+       systems_freebsd = [system_aarch64_freebsd,
+                          system_i386_freebsd,
                           system_x86_64_freebsd];
        systems_netbsd  = [system_i386_netbsd,
                           system_m68k_netbsd,
@@ -443,7 +444,7 @@ interface
 
        { all systems where a value parameter passed by reference must be copied
          on the caller side rather than on the callee side }
-       systems_caller_copy_addr_value_para = [system_aarch64_ios,system_aarch64_darwin,system_aarch64_linux,system_aarch64_win64];
+       systems_caller_copy_addr_value_para = [system_aarch64_ios,system_aarch64_darwin,system_aarch64_linux,system_aarch64_win64,system_aarch64_freebsd];
 
        { pointer checking (requires special code in FPC_CHECKPOINTER,
          and can never work for libc-based targets or any other program
@@ -1134,6 +1135,10 @@ begin
   {$ifdef cpuaarch64}
     default_target(source_info.system);
   {$else cpuaarch64}
+    {$ifdef freebsd}
+      {$define default_target_set}
+      default_target(system_aarch64_freebsd);
+    {$endif freebsd}
     {$if defined(ios)}
       {$define default_target_set}
       default_target(system_aarch64_ios);

+ 81 - 0
compiler/systems/i_bsd.pas

@@ -33,6 +33,82 @@ unit i_bsd;
        systems;
 
     const
+       system_aarch64_freebsd_info : tsysteminfo =
+          (
+            system       : system_aarch64_freebsd;
+            name         : 'FreeBSD for aarch64';
+            shortname    : 'FreeBSD';
+            flags        : [tf_needs_symbol_size,
+                            tf_needs_symbol_type,
+                            tf_files_case_sensitive,
+                            tf_requires_proper_alignment,tf_safecall_exceptions,
+                            tf_smartlink_sections,tf_pic_uses_got,
+                            tf_has_winlike_resources
+{$ifdef llvm}
+                            ,tf_use_psabieh
+{$endif llvm}
+                            ,tf_supports_hidden_symbols
+                            ];
+            cpu          : cpu_aarch64;
+            unit_env     : 'BSDUNITS';
+            extradefines : 'UNIX;HASUNIX;BSD';
+            exeext       : '';
+            defext       : '.def';
+            scriptext    : '.sh';
+            smartext     : '.sl';
+            unitext      : '.ppu';
+            unitlibext   : '.ppl';
+            asmext       : '.s';
+            objext       : '.o';
+            resext       : '.res';
+            resobjext    : '.or';
+            sharedlibext : '.so';
+            staticlibext : '.a';
+            staticlibprefix : 'libp';
+            sharedlibprefix : 'lib';
+            sharedClibext : '.so';
+            staticClibext : '.a';
+            staticClibprefix : 'lib';
+            sharedClibprefix : 'lib';
+            importlibprefix : 'libimp';
+            importlibext : '.a';
+            Cprefix      : '';
+            newline      : #10;
+            dirsep       : '/';
+            assem        : as_gas;
+            assemextern  : as_gas;
+            link         : ld_none;
+            linkextern   : ld_bsd;
+            ar           : ar_gnu_ar;
+            res          : res_elf;
+            dbg          : dbg_dwarf2;            //dbg_stabs;
+            script       : script_unix;
+            endian       : endian_little;
+            alignment    :
+              (
+                procalign       : 8;
+                loopalign       : 4;
+                jumpalign       : 0;
+                jumpalignskipmax    : 0;
+                coalescealign   : 0;
+                coalescealignskipmax: 0;
+                constalignmin   : 0;
+                constalignmax   : 16;
+                varalignmin     : 0;
+                varalignmax     : 16;
+                localalignmin   : 4;
+                localalignmax   : 16;
+                recordalignmin  : 0;
+                recordalignmax  : 16;
+                maxCrecordalign : 16
+              );
+            first_parm_offset : 16;
+            stacksize    : 8*1024*1024;
+            stackalign   : 16;
+            abi          : abi_default;
+            llvmdatalayout : 'e-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128'
+          );
+
        system_i386_freebsd_info : tsysteminfo =
           (
             system       : system_i386_FreeBSD;
@@ -726,6 +802,11 @@ unit i_bsd;
   implementation
 
 initialization
+{$ifdef cpuaarch64}
+  {$ifdef FreeBSD}
+     set_source_info(system_aarch64_freebsd_info);
+  {$endif FreeBSD}
+{$endif cpuaarch64}
 {$ifdef cpui386}
   {$ifdef FreeBSD}
      set_source_info(system_i386_FreeBSD_info);

+ 5 - 0
compiler/systems/t_bsd.pas

@@ -693,6 +693,11 @@ end;
 
 initialization
   RegisterLinker(ld_bsd,TLinkerBSD);
+{$ifdef aarch64}
+  RegisterImport(system_aarch64_freebsd,timportlibbsd);
+  RegisterExport(system_aarch64_freebsd,texportlibbsd);
+  RegisterTarget(system_aarch64_freebsd_info);
+{$endif aarch64}
 {$ifdef x86_64}
   RegisterImport(system_x86_64_dragonfly,timportlibbsd);
   RegisterExport(system_x86_64_dragonfly,texportlibbsd);

+ 2 - 1
compiler/utils/ppuutils/ppudump.pp

@@ -234,7 +234,8 @@ const
   { 111 } 'Darwin-AArch64',
   { 112 } 'AmstradCPC-Z80',
   { 113 } 'SinclairQL-m68k',
-  { 114 } 'WASI-WASM32'
+  { 114 } 'WASI-WASM32',
+  { 115 } 'FreeBSD-AArch64'
   );
 
 const

+ 140 - 0
rtl/bsd/aarch64/syscall.inc

@@ -0,0 +1,140 @@
+{
+  This file is part of the Free Pascal run time library.
+
+  Perform syscall with 0..6 arguments.
+  If syscall return value is negative, negate it, set errno, and return -1.
+
+  Written by Edmund Grimley Evans in 2015 and released into the public domain.
+}
+
+function FpSysCall(sysnr:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_DOSYS0'];
+asm
+  mov w8,w0
+  svc #0
+  b.cc .Ldone
+  str x30,[sp,#-16]!
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_DOSYS1'];
+asm
+  mov w8,w0
+  mov x0,x1
+  svc #0
+  b.cc .Ldone
+  str x30,[sp,#-16]!
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_DOSYS2'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  svc #0
+  b.cc .Ldone
+  str x30,[sp,#-16]!
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_DOSYS3'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  mov x2,x3
+  svc #0
+  b.cc .Ldone
+  str x30,[sp,#-16]!
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_DOSYS4'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  mov x2,x3
+  mov x3,x4
+  svc #0
+  b.cc .Ldone
+  str x30,[sp,#-16]!
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3,param4,param5:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_DOSYS5'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  mov x2,x3
+  mov x3,x4
+  mov x4,x5
+  svc #0
+  b.cc .Ldone
+  str x30,[sp,#-16]!
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3,param4,param5,param6:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_DOSYS6'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  mov x2,x3
+  mov x3,x4
+  mov x4,x5
+  mov x5,x6
+  svc #0
+  b.cc .Ldone
+  str x30,[sp,#-16]!
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;
+
+function FpSysCall(sysnr,param1,param2,param3,param4,param5,param6,param7:TSysParam):TSysResult;
+assembler; nostackframe; [public,alias:'FPC_DOSYS7'];
+asm
+  mov w8,w0
+  mov x0,x1
+  mov x1,x2
+  mov x2,x3
+  mov x3,x4
+  mov x4,x5
+  mov x5,x6
+  mov x6,x7
+  svc #0
+  b.cc .Ldone
+  str x30,[sp,#-16]!
+  bl seterrno
+  ldr x30,[sp],#16
+  mov x0,#-1
+.Ldone:
+end;

+ 38 - 0
rtl/bsd/aarch64/syscallh.inc

@@ -0,0 +1,38 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 2002 Marco van de Voort
+    member of the Free Pascal development team.
+
+    aarch64 syscall headers for *BSD
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    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.
+
+ **********************************************************************}
+
+{$ifdef FPC_USE_SYSCALL}
+
+Type
+
+  TSysResult = int64;   // all platforms, cint=32-bit.
+                        // On platforms with off_t =64-bit, people should
+                        // use int64, and typecast all calls that don't
+                        // return off_t to cint.
+
+  TSysParam  = int64;
+
+function do_sysCall(sysnr:TSysParam):TSysResult; external name 'FPC_DOSYS0';
+function do_sysCall(sysnr,param1:TSysParam):TSysResult; external name 'FPC_DOSYS1';
+function do_sysCall(sysnr,param1,param2:TSysParam):TSysResult;  external name 'FPC_DOSYS2';
+function do_sysCall(sysnr,param1,param2,param3:TSysParam):TSysResult; external name 'FPC_DOSYS3';
+function do_sysCall(sysnr,param1,param2,param3,param4:TSysParam):TSysResult; external name 'FPC_DOSYS4';
+function do_sysCall(sysnr,param1,param2,param3,param4,param5:TSysParam):TSysResult; external name 'FPC_DOSYS5';
+function do_sysCall(sysnr,param1,param2,param3,param4,param5,param6:TSysParam):int64; external name 'FPC_DOSYS6';
+function do_sysCall(sysnr,param1,param2,param3,param4,param5,param6,param7:TSysParam):int64; external name 'FPC_DOSYS7';
+
+{$endif}
+

+ 1 - 1
rtl/bsd/bunxsysc.inc

@@ -376,7 +376,7 @@ end;
 
 function __pipe_call(sysnr:TSysParam):TSysResult; {$ifdef cpui386}oldfpccall{$endif} external name 'FPC_DOSYS0';
 
-{$if defined(freebsd) or defined (dragonfly)}
+{$if (defined(freebsd) or defined (dragonfly)) and (defined(CPUi386) or defined(CPUX86_64))}
   {$define PIPE_RESULT_IN_EAX_AND_EDX}
 {$endif}
 Function FPpipe(var fildes : tfildes):cint;

+ 1 - 0
rtl/freebsd/aarch64/bsyscall.inc

@@ -0,0 +1 @@
+{ nothing }

+ 157 - 0
rtl/freebsd/aarch64/cprt0.as

@@ -0,0 +1,157 @@
+/*
+   Start-up code for Free Pascal Compiler when linking with C library.
+
+*/
+
+	.text
+	.align 2
+#APP
+	.ident  "FreePascal 2.6.x/2.7.x series dynlinked to libc"
+#NO_APP
+	.section        .note.ABI-tag,"a",@progbits
+	.p2align 2
+	.type	abitag, @object
+	.size	abitag, 24
+abitag:
+	.long	8
+	.long	4
+	.long	1
+	.string	"FreeBSD"
+	.long	120000
+.globl __progname
+        .section        .rodata
+
+.LC0:
+	.string ""
+	.data
+	.p2align 3
+	.type	__progname, @object
+	.size	__progname, 8
+__progname:
+	.quad	.LC0
+	.text
+	.p2align 4,,15
+
+	.globl	_start
+	.type	_start,#function
+_start:
+	/* Initialise FP to zero */
+	mov	x29,#0
+
+	/* Get argc, argv, envp */
+	ldr	x1,[x0]
+	add	x2,x0,#8
+	add	x3,x1,#1
+	add	x3,x2,x3,lsl #3
+
+	/* Save argc, argv, envp, environ, __progname and initial stack pointer */
+	adrp	x10,:got:operatingsystem_parameter_argc
+	ldr	x10,[x10,#:got_lo12:operatingsystem_parameter_argc]
+	str	x1,[x10]
+	adrp	x10,:got:operatingsystem_parameter_argv
+	ldr	x10,[x10,#:got_lo12:operatingsystem_parameter_argv]
+	str	x2,[x10]
+	adrp	x10,:got:operatingsystem_parameter_envp
+	ldr	x10,[x10,#:got_lo12:operatingsystem_parameter_envp]
+	str	x3,[x10]
+
+	/* save environ */
+	adrp	x10,environ
+	ldr	x10,[x10,:lo12:environ]
+	cbnz	x10,.LBB0_2
+	ldr	x10,=environ
+	str	x3,[x10]
+.LBB0_2:
+	/* save __progname */
+        ldr     w8,=operatingsystem_parameter_argc
+        cmp     w8,#0
+        cset    w8,le
+        tbnz    w8,#0,.LBB0_9
+// %bb.1:
+	adrp	x8,operatingsystem_parameter_argv
+        ldr     x8,[x8,:lo12:operatingsystem_parameter_argv]
+        cbz     x8,.LBB0_9
+// %bb.2:
+	ldr	x2,[x2]
+	adrp	x9,__progname
+	adrp	x10,__progname
+	add	x10,x10,:lo12:__progname
+	str	x2,[x10]
+	ldr	x8,[x9,:lo12:__progname]
+	adrp	x9,s
+	add	x9,x9,:lo12:s
+	str	x8,[x9]
+.LBB0_3:
+	adrp	x8,s
+	ldr	x8,[x8,:lo12:s]
+	ldrb	w9,[x8]
+	cbz	w9,.LBB0_8
+// %bb.4:
+	adrp	x8,s
+	ldr	x8,[x8, :lo12:s]
+	ldrb	w9,[x8]
+	cmp	w9,#47
+	b.ne	.LBB0_6
+// %bb.5:
+	adrp	x8,s
+	ldr	x8,[x8,:lo12:s]
+	add	x8,x8,#1
+	adrp	x9,__progname
+	add	x9,x9,:lo12:__progname
+	str	x8,[x9]
+.LBB0_6:
+// %bb.7:
+	adrp	x8,s
+	adrp	x9,s
+	add	x9,x9,:lo12:s
+	ldr	x8,[x8,:lo12:s]
+	add	x8,x8,#1
+	str	x8,[x9]
+	b	.LBB0_3
+.LBB0_8:
+.LBB0_9:
+	/* save stack pointer */
+	adrp	x10,:got:__stkptr
+	ldr	x10,[x10,#:got_lo12:__stkptr]
+	mov	x6,sp
+	str	x6,[x10]
+
+	bl	PASCALMAIN
+
+	/* This should never happen */
+	b	abort
+
+	.globl	_haltproc
+	.type	_haltproc,#function
+_haltproc:
+	adrp	x0,:got:operatingsystem_result
+	ldr	x0,[x0,#:got_lo12:operatingsystem_result]
+	ldr	w0,[x0]
+	mov	w8,#1 // SYS_exit
+	svc	#0
+	b	_haltproc
+
+	/* Define a symbol for the first piece of initialized data. */
+	.data
+	.align 3
+	.globl __data_start
+__data_start:
+	.long 0
+	.weak data_start
+	data_start = __data_start
+
+	.bss
+	.align 3
+
+	.comm __stkptr,8
+
+	.comm operatingsystem_parameter_envp,8
+	.comm operatingsystem_parameter_argc,8
+	.comm operatingsystem_parameter_argv,8
+	.comm environ,8,8
+
+s:
+        .xword  0
+        .size   s, 8
+
+	.section .note.GNU-stack,"",%progbits

+ 138 - 0
rtl/freebsd/aarch64/dllprt0.as

@@ -0,0 +1,138 @@
+/*
+   Start-up code for Free Pascal Compiler in a shared library,
+   not linking with C library.
+
+*/
+
+	.text
+	.align 2
+
+	.globl	_startlib
+	.type	_startlib,#function
+_startlib:
+	.globl	FPC_SHARED_LIB_START
+	.type	FPC_SHARED_LIB_START,#function
+FPC_SHARED_LIB_START:
+	stp	x29,x30,[sp,#-16]!
+
+	/* Get argc, argv, envp */
+	ldr	x1,[x0]
+	add	x2,x0,#8
+	add	x3,x1,#1
+	add	x3,x2,x3,lsl #3
+
+	/* Save argc, argv and envp */
+	adrp	x9,:got:operatingsystem_parameter_argc
+	ldr	x9,[x9,#:got_lo12:operatingsystem_parameter_argc]
+	str	x1,[x9]
+	adrp	x9,:got:operatingsystem_parameter_argv
+	ldr	x9,[x9,#:got_lo12:operatingsystem_parameter_argv]
+	str	x2,[x9]
+	adrp	x9,:got:operatingsystem_parameter_envp
+	ldr	x9,[x9,#:got_lo12:operatingsystem_parameter_envp]
+	str	x3,[x9]
+
+	/* save environ */
+	adrp	x10,environ
+	ldr	x10,[x10,:lo12:environ]
+	cbnz	x10,.LBB0_2
+	adrp	x10,environ
+	add	x10,x9,:lo12:environ
+	str	x3,[x10]
+.LBB0_2:
+	/* save __progname */
+	adrp	x8,:got:operatingsystem_parameter_argc
+	ldr	x8,[x8,#:got_lo12:operatingsystem_parameter_argc]
+        cmp     x8,#0
+        cset    x8,le
+        tbnz    x8,#0,.LBB0_9
+// %bb.1:
+	adrp	x8,operatingsystem_parameter_argv
+        ldr     x8,[x8,:got_lo12:operatingsystem_parameter_argv]
+        cbz     x8,.LBB0_9
+// %bb.2:
+	ldr	x2,[x2]
+	adrp	x9,:got:__progname
+	adrp	x10,:got:__progname
+	add	x10,x10,:lo12:__progname
+	str	x2,[x10]
+	ldr	x8,[x9,:got_lo12:__progname]
+	adrp	x9,s
+	add	x9,x9,:lo12:s
+	str	x8,[x9]
+.LBB0_3:
+	adrp	x8,s
+	ldr	x8,[x8,:lo12:s]
+	ldrb	w9,[x8]
+	cbz	w9,.LBB0_8
+// %bb.4:
+	adrp	x8,s
+	ldr	x8,[x8, :lo12:s]
+	ldrb	w9,[x8]
+	cmp	w9,#47
+	b.ne	.LBB0_6
+// %bb.5:
+	adrp	x8,s
+	ldr	x8,[x8,:lo12:s]
+	add	x8,x8,#1
+	adrp	x9,:got:__progname
+	add	x9,x9,:lo12:__progname
+	str	x8,[x9]
+.LBB0_6:
+// %bb.7:
+	adrp	x8,s
+	adrp	x9,s
+	add	x9,x9,:lo12:s
+	ldr	x8,[x8,:lo12:s]
+	add	x8,x8,#1
+	str	x8,[x9]
+	b	.LBB0_3
+.LBB0_8:
+.LBB0_9:
+	/* Save initial stackpointer */
+	adrp	x9,:got:__stkptr
+	ldr	x9,[x9,#:got_lo12:__stkptr]
+	mov	x10,sp
+	str	x10,[x9]
+
+	/* Call main */
+	bl	PASCALMAIN
+
+	/* Return */
+	ldp	x29,x30,[sp],#16
+	ret
+
+	.globl	_haltproc
+	.type	_haltproc,#function
+_haltproc:
+	adrp	x0,:got:operatingsystem_result
+	ldr	x0,[x0,#:got_lo12:operatingsystem_result]
+	ldr	w0,[x0]
+	mov	w8,#1 // SYS_exit
+	svc	#0
+	b	_haltproc
+
+	/* Define a symbol for the first piece of initialized data. */
+	.data
+	.align 3
+	.globl __data_start
+__data_start:
+	.long 0
+	.weak data_start
+	data_start = __data_start
+
+	.bss
+	.align 3
+
+	.comm __stkptr,8
+
+	.comm operatingsystem_parameter_envp,8
+	.comm operatingsystem_parameter_argc,8
+	.comm operatingsystem_parameter_argv,8
+	.comm environ,8,8
+
+s:
+        .xword  0
+        .size   s, 8
+
+	.section .note.GNU-stack,"",%progbits

+ 166 - 0
rtl/freebsd/aarch64/gprt0.as

@@ -0,0 +1,166 @@
+/*
+   Start-up code for Free Pascal Compiler when linking with C library
+   with profiling support.
+*/
+
+	.text
+	.align 2
+
+	.globl _start
+	.type _start,#function
+_start:
+	/* Initialise FP to zero */
+	mov	x29,#0
+
+	/* Get argc, argv, envp */
+	ldr	x1,[x0]
+	add	x2,x0,#8
+	add	x11,x1,#1
+	add	x11,x2,x11,lsl #3
+
+	/* Save argc, argv, envp, and initial stack pointer */
+	adrp	x10,:got:operatingsystem_parameter_argc
+	ldr	x10,[x10,#:got_lo12:operatingsystem_parameter_argc]
+	str	x1,[x10]
+	adrp	x10,:got:operatingsystem_parameter_argv
+	ldr	x10,[x10,#:got_lo12:operatingsystem_parameter_argv]
+	str	x2,[x10]
+	adrp	x10,:got:operatingsystem_parameter_envp
+	ldr	x10,[x10,#:got_lo12:operatingsystem_parameter_envp]
+	str	x3,[x10]
+
+	/* save environ */
+	adrp	x10,environ
+	ldr	x10,[x10,:lo12:environ]
+	cbnz	x10,.LBB0_2
+	ldr	x10,=environ
+	str	x3,[x10]
+.LBB0_2:
+	/* save __progname */
+        ldr     w8,=operatingsystem_parameter_argc
+        cmp     w8,#0
+        cset    w8,le
+        tbnz    w8,#0,.LBB0_9
+// %bb.1:
+	adrp	x8,operatingsystem_parameter_argv
+        ldr     x8,[x8,:lo12:operatingsystem_parameter_argv]
+        cbz     x8,.LBB0_9
+// %bb.2:
+	ldr	x2,[x2]
+	adrp	x9,__progname
+	adrp	x10,__progname
+	add	x10,x10,:lo12:__progname
+	str	x2,[x10]
+	ldr	x8,[x9,:lo12:__progname]
+	adrp	x9,s
+	add	x9,x9,:lo12:s
+	str	x8,[x9]
+.LBB0_3:
+	adrp	x8,s
+	ldr	x8,[x8,:lo12:s]
+	ldrb	w9,[x8]
+	cbz	w9,.LBB0_8
+// %bb.4:
+	adrp	x8,s
+	ldr	x8,[x8, :lo12:s]
+	ldrb	w9,[x8]
+	cmp	w9,#47
+	b.ne	.LBB0_6
+// %bb.5:
+	adrp	x8,s
+	ldr	x8,[x8,:lo12:s]
+	add	x8,x8,#1
+	adrp	x9,__progname
+	add	x9,x9,:lo12:__progname
+	str	x8,[x9]
+.LBB0_6:
+// %bb.7:
+	adrp	x8,s
+	adrp	x9,s
+	add	x9,x9,:lo12:s
+	ldr	x8,[x8,:lo12:s]
+	add	x8,x8,#1
+	str	x8,[x9]
+	b	.LBB0_3
+.LBB0_8:
+.LBB0_9:
+	adrp	x10,:got:__stkptr
+	ldr	x10,[x10,#:got_lo12:__stkptr]
+	mov	x6,sp
+	str	x6,[x10]
+
+	bl	main
+
+	/* This should never happen */
+	b	abort
+
+	.globl	_init_dummy
+	.type	_init_dummy,#function
+_init_dummy:
+	ret
+
+	.globl	_fini_dummy
+	.type	_fini_dummy,#function
+_fini_dummy:
+	ret
+
+	.globl	main_stub
+	.type	main_stub,#function
+main_stub:
+	stp	x29,x30,[sp,#-16]!
+
+	/* Save initial stackpointer */
+	mov	x0,sp
+	adrp	x1,:got:__stkptr
+	ldr	x1,[x1,#:got_lo12:__stkptr]
+	str	x0,[x1]
+
+	/* Initialize gmon */
+	adrp	x0,:got:_start
+	ldr	x0,[x0,#:got_lo12:_start]
+	adrp	x1,:got:_etext
+	ldr	x1,[x1,#:got_lo12:_etext]
+	bl	__monstartup
+	adrp	x0,:got:_mcleanup
+	ldr	x0,[x0,#:got_lo12:_mcleanup]
+	bl	atexit
+
+	/* Start the program */
+	bl	 PASCALMAIN
+	b	 abort
+
+	.globl	_haltproc
+	.type	_haltproc,#function
+_haltproc:
+	/* Return to libc */
+	adrp	x1,:got:__stkptr
+	ldr	x1,[x1,#:got_lo12:__stkptr]
+	ldr	x1,[x1]
+	mov	sp,x1
+	ldp	x29,x30,[sp],#16
+	ret
+
+	/* Define a symbol for the first piece of initialized data. */
+	.data
+	.align 3
+	.globl __data_start
+__data_start:
+	.long 0
+	.weak data_start
+	data_start = __data_start
+
+	.bss
+	.align 3
+
+	.comm __stkptr,8
+
+	.comm operatingsystem_parameter_envp,8
+	.comm operatingsystem_parameter_argc,8
+	.comm operatingsystem_parameter_argv,8
+	.comm environ,8,8
+
+s:
+        .xword  0
+        .size   s, 8
+
+	.section .note.GNU-stack,"",%progbits

+ 147 - 0
rtl/freebsd/aarch64/prt0.as

@@ -0,0 +1,147 @@
+/*
+   Start-up code for Free Pascal Compiler, not in a shared library,
+   not linking with C library.
+*/
+
+	.text
+	.align 2
+
+#APP
+	.ident  "FreeBSD"
+#NO_APP
+	.section        .note.ABI-tag,"a",@progbits
+	.p2align 2
+	.type	abitag, @object
+	.size	abitag, 24
+abitag:
+	.long	8
+	.long	4
+	.long	1
+	.string	"FreeBSD"
+	.long	120000
+
+	.section        .rodata
+.LC0:
+	.string ""
+.globl __progname
+	.data
+	.p2align 3
+	.type	__progname, @object
+	.size	__progname, 8
+__progname:
+	.quad	.LC0
+	.text
+	.p2align 2,,3
+
+	.globl	_start
+	.type	_start,#function
+_start:
+	/* Initialise FP to zero */
+	mov	x29,#0
+
+	/* Get argc, argv, envp */
+	ldr	x1,[x0]
+	add	x2,x0,#8
+	add	x11,x1,#1
+	add	x11,x2,x11,lsl #3
+
+	/* Save argc, argv, envp, environ, __progname and initial stack pointer */
+	ldr	x10,=operatingsystem_parameter_argc
+	str	x1,[x10]
+	ldr	x10,=operatingsystem_parameter_argv
+	str	x2,[x10]
+	ldr	x10,=operatingsystem_parameter_envp
+	str	x11,[x10]
+
+	/* save environ */
+	adrp	x10,environ
+	ldr	x10,[x10,:lo12:environ]
+	cbnz	x10,.LBB0_2
+	ldr	x10,=environ
+	str	x11,[x10]
+.LBB0_2:
+	/* save __progname */
+        ldr     w8,=operatingsystem_parameter_argc
+        cmp     w8,#0
+        cset    w8,le
+        tbnz    w8,#0,.LBB0_9
+// %bb.1:
+	adrp	x8,operatingsystem_parameter_argv
+        ldr     x8,[x8,:lo12:operatingsystem_parameter_argv]
+        cbz     x8,.LBB0_9
+// %bb.2:
+	ldr	x2,[x2]
+	adrp	x9,__progname
+	adrp	x10,__progname
+	add	x10,x10,:lo12:__progname
+	str	x2,[x10]
+	ldr	x8,[x9,:lo12:__progname]
+	adrp	x9,s
+	add	x9,x9,:lo12:s
+	str	x8,[x9]
+.LBB0_3:
+	adrp	x8,s
+	ldr	x8,[x8,:lo12:s]
+	ldrb	w9,[x8]
+	cbz	w9,.LBB0_8
+// %bb.4:
+	adrp	x8,s
+	ldr	x8,[x8, :lo12:s]
+	ldrb	w9,[x8]
+	cmp	w9,#47
+	b.ne	.LBB0_6
+// %bb.5:
+	adrp	x8,s
+	ldr	x8,[x8,:lo12:s]
+	add	x8,x8,#1
+	adrp	x9,__progname
+	add	x9,x9,:lo12:__progname
+	str	x8,[x9]
+.LBB0_6:
+// %bb.7:
+	adrp	x8,s
+	adrp	x9,s
+	add	x9,x9,:lo12:s
+	ldr	x8,[x8,:lo12:s]
+	add	x8,x8,#1
+	str	x8,[x9]
+	b	.LBB0_3
+.LBB0_8:
+.LBB0_9:
+	/* save stack pointer */
+	ldr	x10,=__stkptr
+	mov	x6,sp
+	str	x6,[x10]
+
+	/* Call main */
+	bl	PASCALMAIN
+
+	ldr	x10,=operatingsystem_result
+	ldr	w0,[x10]
+	mov	w8,#1 // SYS_exit
+	svc	#0
+
+	/* Define a symbol for the first piece of initialized data. */
+	.data
+	.align 3
+	.globl __data_start
+__data_start:
+	.long 0
+	.weak data_start
+	data_start = __data_start
+
+	.bss
+	.align 3
+
+	.comm __stkptr,8
+
+	.comm operatingsystem_parameter_envp,8
+	.comm operatingsystem_parameter_argc,8
+	.comm operatingsystem_parameter_argv,8
+	.comm environ,8,8
+
+s:
+        .xword  0
+        .size   s, 8
+
+	.section .note.GNU-stack,"",%progbits

+ 89 - 0
rtl/freebsd/aarch64/si_c.inc

@@ -0,0 +1,89 @@
+
+Type
+    TCleanup = procedure; cdecl;
+
+var
+  environ : ppchar; cvar; public  name '__environ';
+  progname: pchar = #0#0; cvar; public name '__progname';
+  dynamic : pchar;  external name '_DYNAMIC'; // #pragma weak
+
+procedure atexit(prc:TCleanup); cdecl external name 'atexit';
+procedure cleanup(prc:TCleanup); cdecl external name 'cleanup';
+procedure init_tls; cdecl; external name 'init_tls';
+procedure fini; cdecl; external name '_fini';
+procedure init; cdecl; external name '_init';
+procedure libc_exit(exitcode:longint);cdecl; external name 'exit';
+function  main(nrarg:longint;pp:ppchar;env:ppchar):longint; cdecl; external name 'main';
+
+{$ifdef gcrt}
+ procedure cmcleanup; cdecl; external name '_mcleanup';
+ procedure monstratup(p,p2:pointer); cdecl; external name 'monstartup';
+
+var
+ eprol:longint; external name 'eprol';
+ etext:longint; external name 'etext';
+{$endif}
+
+procedure start(ap:ppchar;cleanup:TCleanup);
+
+var argc: longint;
+    argv: ppchar;
+    env : ppchar;
+    s   : pchar;
+begin
+  argc:=plongint(ap)^;
+  argv:=ppchar(ap[1]);
+  env:=	ppchar(ap[2+argc]);
+  environ:=env;
+  if (argc>0) and (argv[0]<>#0) Then
+   begin
+     progname:=argv[0];
+     s:=progname;
+     while s^<>#0 do
+        begin
+          if s^='/' then
+            progname:=@s[1];
+          inc(s);
+	end;
+    end;
+  if assigned(pchar(@dynamic)) then // I suspect this is a trick to find
+				    // out runtime if we are shared
+				    // linking, so the same code can be used
+				    // for static and shared linking
+    atexit(cleanup)
+  else
+    init_tls;
+  {$ifdef GCRT}
+    atexit(@_mcleanup);
+  {$endif}
+  atexit(@fini);
+  {$ifdef GCRT}
+    monstartup(@eprol,@etext);
+   asm
+    eprol:
+   end;
+  {$endif}
+  init;
+  libc_exit(main(argc,argv,env)); // doesn't return
+ asm
+     { We need this stuff to make gdb behave itself, otherwise
+      gdb will chokes with SIGILL when trying to debug apps.
+    }
+    .section ".note.ABI-tag", "a"
+    .align 4
+    .long 8
+    .long 4
+    .long  1
+    .asciz "FreeBSD"
+    .align 4
+    .long	900044
+    .align 4
+    .section	.note.GNU-stack,"",@progbits
+  end;
+end;
+
+
+
+begin
+end.
+

+ 43 - 0
rtl/freebsd/aarch64/sighnd.inc

@@ -0,0 +1,43 @@
+{
+    This file is part of the Free Pascal run time library.
+    Copyright (c) 1999-2000 by Michael Van Canneyt,
+    member of the Free Pascal development team.
+
+    Signal handler is arch dependant due to processor to language
+    exception conversion.
+
+    See the file COPYING.FPC, included in this distribution,
+    for details about the copyright.
+
+    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.
+
+ **********************************************************************}
+
+{ procedure SignalToRunerror(Sig: longint; SigInfo: PSigInfo; UContext: PUContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl; }
+procedure SignalToRunerror(Sig: cint; info : psiginfo;  SigContext:PSigContext); public name '_FPC_DEFAULTSIGHANDLER'; cdecl;
+
+var
+  res : word;
+begin
+  res:=0;
+  case sig of
+    SIGFPE:
+        res:=207;
+    SIGILL:
+        res:=216;
+    SIGSEGV :
+        res:=216;
+    SIGBUS:
+        res:=214;
+    SIGINT:
+        res:=217;
+    SIGQUIT:
+        res:=233;
+  end;
+  reenable_signal(sig);
+  { give runtime error at the position where the signal was raised }
+  if res<>0 then
+    HandleError(res);
+end;

+ 7 - 0
rtl/freebsd/signal.inc

@@ -80,6 +80,7 @@ type sigset_t = array[0..3] of Longint;
 
     psigcontext = ^sigcontextrec;
     PSigContextRec = ^SigContextRec;
+{$if (defined(CPUi386) or defined(CPUX86_64))}
     SigContextRec = record
        sc_mask      : sigset_t;          { signal mask to restore }
        sc_onstack   : longint;              { sigstack state to restore }
@@ -120,8 +121,14 @@ type sigset_t = array[0..3] of Longint;
        fpr_ex_sw    : cardinal;
        fpr_pad      : array[0..63] of char;
        end;
+{$endif def x86}
 
 
+{$ifdef CPUAARCH64}
+        SigContextRec = record
+            _dummy : cint;
+        end;
+{$endif cpuaarch64}
 
   Sigval = Record
             Case Boolean OF

+ 28 - 0
rtl/freebsd/ucontexth.inc

@@ -20,6 +20,7 @@ type
   end;
   {$packrecords C}
 
+{$if (defined(CPUi386) or defined(CPUX86_64))}
   mcontext_t = record
     {*
      * The first 20 fields must match the definition of
@@ -53,7 +54,34 @@ type
     mc_fpstate: TMCFPStateArray;
     mc_spare2: array[0..7] of cInt;
   end;
+{$endif def x86}
 
+{$ifdef CPUAARCH64}
+  gpregs = record
+    gp_x: array[0..30] of cInt; { __register_t gp_x[30]; }
+    gp_lr: cInt;
+    gp_sp: cInt;
+    gp_elr: cInt;
+    gp_spsr: cuint32;
+    gp_pad: cInt;
+  end;
+
+  fpregs = record
+    fp_q: array[0..64] of cInt; { __uint128_t fp_q[32] }
+    fp_sr: cuint32;
+    fp_cr: cuint32;
+    fp_flags: cInt;
+    fp_pad: cInt;
+  end;
+
+  mcontext_t = record
+    mc_gpregs: gpregs;
+    mc_fpregs: fpregs;
+    mc_flags: cint32;
+    mc_pad: cint32;
+    mc_spare: array[0..8] of cInt;
+  end;
+{$endif cpuaarch64}
 
   pucontext_t = ^ucontext_t;
   ucontext_t = record  // required for kse threads

+ 1 - 1
utils/fpcm/fpcmmain.pp

@@ -123,7 +123,7 @@ interface
         { go32v2 }  ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false,  false, false, false,  false,  false, false),
         { win32 }   ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false,  false, false, false,  false,  false, false),
         { os2 }     ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false,  false, false, false,  false,  false, false),
-        { freebsd } ( true,  false, false, false, true,  false, false, false, false, false, false, false, false, false,   false, false, false,  false, false, false,  false,  false, false),
+        { freebsd } ( true,  false, false, false, true,  false, false, false, false, false, false, false, false, false,   false, false, true,   false, false, false,  false,  false, false),
         { beos }    ( true,  false, false, false, false, false, false, false, false, false, false, false, false, false,   false, false, false,  false, false, false,  false,  false, false),
         { haiku }   ( true,  false, false, false, true,  false, false, false, false, false, false, false, false, false,   false, false, false,  false, false, false,  false,  false, false),
         { netbsd }  ( true,  true,  true,  true,  true,  true,  false, false, false, false, false, false, false, false,   false, false, false,  false, false, false,  false,  false, false),