From 4a1db1dc797edb2d8f5aa89ec3b8fe9e8b2137c3 Mon Sep 17 00:00:00 2001 From: Karoly Balogh Date: Sun, 19 Nov 2023 13:21:12 +0100 Subject: [PATCH] m68k: initial compiler changes for Human68k (Sharp X68000) support --- compiler/aggas.pas | 3 +- compiler/compiler.pas | 3 + compiler/m68k/ag68kvasm.pas | 5 +- compiler/m68k/cputarg.pas | 3 + compiler/msg/errore.msg | 1 + compiler/options.pas | 9 +- compiler/systems.inc | 6 +- compiler/systems/i_human68k.pas | 108 ++++++++++++ compiler/systems/t_human68k.pas | 254 +++++++++++++++++++++++++++++ compiler/utils/ppuutils/ppudump.pp | 3 +- 10 files changed, 386 insertions(+), 9 deletions(-) create mode 100644 compiler/systems/i_human68k.pas create mode 100644 compiler/systems/t_human68k.pas diff --git a/compiler/aggas.pas b/compiler/aggas.pas index 3edd3e3b7f..be445b9adf 100644 --- a/compiler/aggas.pas +++ b/compiler/aggas.pas @@ -512,7 +512,8 @@ implementation system_i386_EMX: ; system_m68k_atari, { atari tos/mint GNU AS also doesn't seem to like .section (KB) } system_m68k_amiga, { amiga has old GNU AS (2.14), which blews up from .section (KB) } - system_m68k_sinclairql: { same story, only ancient GNU tools available (KB) } + system_m68k_sinclairql, { same story, only ancient GNU tools available (KB) } + system_m68k_human68k: { see above... (KB) } begin { ... but vasm is GAS compatible on amiga/atari, and supports named sections } if create_smartlink_sections then diff --git a/compiler/compiler.pas b/compiler/compiler.pas index bf066a7855..dff6c4571f 100644 --- a/compiler/compiler.pas +++ b/compiler/compiler.pas @@ -97,6 +97,9 @@ uses {$ifdef haiku} ,i_haiku {$endif haiku} +{$ifdef human68k} + ,i_human68k +{$endif human68k} {$ifdef linux} ,i_linux {$endif linux} diff --git a/compiler/m68k/ag68kvasm.pas b/compiler/m68k/ag68kvasm.pas index 6e7067af67..512125b78b 100644 --- a/compiler/m68k/ag68kvasm.pas +++ b/compiler/m68k/ag68kvasm.pas @@ -102,7 +102,8 @@ unit ag68kvasm; system_m68k_amiga, system_m68k_atari, system_m68k_embedded, - system_m68k_sinclairql: objtype:='-Felf'; + system_m68k_sinclairql, + system_m68k_human68k: objtype:='-Felf'; else internalerror(2016052601); end; @@ -136,7 +137,7 @@ unit ag68kvasm; idtxt : 'VASM'; asmbin : 'vasmm68k_std'; asmcmd: '-quiet -elfregs -gas $OTYPE $ARCH -o $OBJ $EXTRAOPT $ASM'; - supported_targets : [system_m68k_amiga,system_m68k_atari,system_m68k_sinclairql,system_m68k_embedded]; + supported_targets : [system_m68k_amiga,system_m68k_atari,system_m68k_sinclairql,system_m68k_human68k,system_m68k_embedded]; flags : [af_needar,af_smartlink_sections]; labelprefix : '.L'; labelmaxlen : -1; diff --git a/compiler/m68k/cputarg.pas b/compiler/m68k/cputarg.pas index c6d080bd07..3f7ef420cb 100644 --- a/compiler/m68k/cputarg.pas +++ b/compiler/m68k/cputarg.pas @@ -56,6 +56,9 @@ implementation {$ifndef NOTARGETSINCLAIRQL} ,t_sinclairql {$endif} + {$ifndef NOTARGETHUMAN68K} + ,t_human68k + {$endif} {$ifndef NOTARGETEMBEDDED} ,t_embed {$endif} diff --git a/compiler/msg/errore.msg b/compiler/msg/errore.msg index 807b816737..ffb0b5dc65 100644 --- a/compiler/msg/errore.msg +++ b/compiler/msg/errore.msg @@ -4282,6 +4282,7 @@ F*2P_Set target CPU (aarch64,arm,avr,i386,i8086,jvm,m68k,mips,mipsel,powerpc, 6*2Tmacosclassic_Classic Mac OS 6*2Tpalmos_PalmOS 6*2Tsinclairql_Sinclair QL +6*2Thuman68k_Human 68k # i8086 targets 8*2Tembedded_Embedded 8*2Tmsdos_MS-DOS (and compatible) diff --git a/compiler/options.pas b/compiler/options.pas index 22ab324f74..eecaa9b7a1 100644 --- a/compiler/options.pas +++ b/compiler/options.pas @@ -2175,6 +2175,8 @@ begin target_unsup_features:=[f_threading]; system_m68k_atari: target_unsup_features:=[f_threading]; + system_m68k_human68k: + target_unsup_features:=[f_threading,f_dynlibs]; { classic amiga has dynamic libraries, but they cannot be integrated in the normal dynlibs infrastructure due to architectural differences, so therefore lets disable the feature. } @@ -2201,8 +2203,8 @@ begin include(init_settings.globalswitches,cs_link_vlink); {$endif} {$ifdef m68k} - { always enable vlink as default linker for the Sinclair QL and Atari } - if (target_info.system in [system_m68k_sinclairql,system_m68k_atari]) and + { always enable vlink as default linker for the Sinclair QL, Atari, and Human 68k } + if (target_info.system in [system_m68k_sinclairql,system_m68k_atari,system_m68k_human68k]) and not LinkerSetExplicitly then include(init_settings.globalswitches,cs_link_vlink); {$endif m68k} @@ -5511,7 +5513,8 @@ begin end; end; system_m68k_atari, - system_m68k_sinclairql: + system_m68k_sinclairql, + system_m68k_human68k: begin if not option.CPUSetExplicitly then init_settings.cputype:=cpu_mc68000; diff --git a/compiler/systems.inc b/compiler/systems.inc index a62dcb85d5..3c22ae2fa6 100644 --- a/compiler/systems.inc +++ b/compiler/systems.inc @@ -213,7 +213,8 @@ system_mips64el_linux, { 118 } system_riscv32_freertos, { 119 } system_loongarch64_linux, { 120 } - system_aarch64_iphonesim { 121 } + system_aarch64_iphonesim, { 121 } + system_m68k_human68k { 122 } ); type @@ -331,7 +332,8 @@ ld_msxdos, ld_amstradcpc, ld_sinclairql, - ld_wasi + ld_wasi, + ld_human68k ); tar = (ar_none diff --git a/compiler/systems/i_human68k.pas b/compiler/systems/i_human68k.pas new file mode 100644 index 0000000000..84af86d5b7 --- /dev/null +++ b/compiler/systems/i_human68k.pas @@ -0,0 +1,108 @@ +{ + Copyright (c) 2023 by Karoly Balogh + + This unit implements support information structures for Human 68k, + the operating system of the Sharp X68000 + + 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 of the License, 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + **************************************************************************** +} +{ This unit implements support information structures for Human 68k. } +unit i_human68k; + +{$i fpcdefs.inc} + + interface + + uses + systems; + + const + system_m68k_human68k_info : tsysteminfo = + ( + system : system_m68k_human68k; + name : 'Human 68k'; + shortname : 'human68k'; + flags : [tf_use_8_3,tf_requires_proper_alignment, + tf_smartlink_sections,tf_under_development]; + cpu : cpu_m68k; + unit_env : ''; + extradefines : ''; + exeext : '.x'; + defext : ''; + scriptext : ''; + smartext : '.sl'; + unitext : '.ppu'; + unitlibext : '.ppl'; + asmext : '.s'; + objext : '.o'; + resext : '.res'; + resobjext : '.or'; + sharedlibext : '.dll'; + staticlibext : '.a'; + staticlibprefix : ''; + sharedlibprefix : ''; + sharedClibext : '.dll'; + staticClibext : '.a'; + staticClibprefix : 'lib'; + sharedClibprefix : ''; + importlibprefix : 'libimp'; + importlibext : '.a'; + Cprefix : '_'; + newline : #10; + dirsep : '/'; { ... the underlying tools (binutils/vlink/vasm) prefer Unix paths } + assem : as_m68k_vasm; + assemextern : as_m68k_vasm; + link : ld_none; + linkextern : ld_human68k; + ar : ar_gnu_ar; + res : res_ext; + dbg : dbg_stabs; + script : script_unix; + endian : endian_big; + alignment : + ( + procalign : 4; + loopalign : 4; + jumpalign : 0; + jumpalignskipmax : 0; + coalescealign : 0; + coalescealignskipmax: 0; + constalignmin : 0; + constalignmax : 4; + varalignmin : 0; + varalignmax : 4; + localalignmin : 0; + localalignmax : 4; + recordalignmin : 0; + recordalignmax : 2; + maxCrecordalign : 4 + ); + first_parm_offset : 8; + stacksize : 8192; + stackalign : 2; + abi : abi_default; + llvmdatalayout : 'todo'; + ); + + implementation + +initialization +{$ifdef cpu68} + {$ifdef human68k} + set_source_info(system_m68k_human68k_info); + {$endif human68k} +{$endif cpu68} +end. diff --git a/compiler/systems/t_human68k.pas b/compiler/systems/t_human68k.pas new file mode 100644 index 0000000000..83d8437452 --- /dev/null +++ b/compiler/systems/t_human68k.pas @@ -0,0 +1,254 @@ +{ + Copyright (c) 2020 by Free Pascal Development Team + + This unit implements support import, export, link routines + for the Human 68k (a.k.a. Sharp X68000) target + + 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 of the License, 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, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + + **************************************************************************** +} +unit t_human68k; + +{$i fpcdefs.inc} + +interface + + uses + rescmn, comprsrc, link; + +type + PLinkerHuman68k = ^TLinkerHuman68k; + TLinkerHuman68k = class(texternallinker) + private + Origin: DWord; + UseVLink: boolean; + function WriteResponseFile(isdll: boolean): boolean; + procedure SetHuman68kInfo; + function MakeHuman68kExe: boolean; + public + constructor Create; override; + procedure SetDefaultInfo; override; + procedure InitSysInitUnitName; override; + function MakeExecutable: boolean; override; + end; + + +implementation + + uses + sysutils,cutils,cfileutl,cclasses,aasmbase, + globtype,globals,systems,verbose,cscript,fmodule,i_human68k; + + +constructor TLinkerHuman68k.Create; +begin + UseVLink:=(cs_link_vlink in current_settings.globalswitches); + + Inherited Create; + { allow duplicated libs (PM) } + SharedLibFiles.doubles:=true; + StaticLibFiles.doubles:=true; +end; + + +procedure TLinkerHuman68k.SetHuman68kInfo; +begin + with Info do + begin + if not UseVLink then + begin + ExeCmd[1]:='ld $DYNLINK $OPT -d -n -o $EXE $RES'; + end + else + begin + ExeCmd[1]:='vlink $QLFLAGS $FLAGS $GCSECTIONS $OPT $STRIP $MAP -o $EXE -T $RES'; + end; + end; +end; + + +procedure TLinkerHuman68k.SetDefaultInfo; +begin + if target_info.system = system_m68k_human68k then + SetHuman68kInfo; +end; + + +procedure TLinkerHuman68k.InitSysInitUnitName; +begin + sysinitunit:='si_prc'; +end; + + +function TLinkerHuman68k.WriteResponseFile(isdll: boolean): boolean; +var + linkres : TLinkRes; + HPath : TCmdStrListItem; + s : string; +begin + WriteResponseFile:=False; + + { Open link.res file } + LinkRes:=TLinkRes.Create(outputexedir+Info.ResName,true); + if UseVLink and (source_info.dirsep <> '/') then + LinkRes.fForceUseForwardSlash:=true; + + { Write path to search libraries } + HPath:=TCmdStrListItem(current_module.locallibrarysearchpath.First); + while assigned(HPath) do + begin + s:=HPath.Str; + if (cs_link_on_target in current_settings.globalswitches) then + s:=ScriptFixFileName(s); + LinkRes.Add('-L'+s); + HPath:=TCmdStrListItem(HPath.Next); + end; + HPath:=TCmdStrListItem(LibrarySearchPath.First); + while assigned(HPath) do + begin + s:=HPath.Str; + if s<>'' then + LinkRes.Add('SEARCH_DIR("'+s+'")'); + HPath:=TCmdStrListItem(HPath.Next); + end; + + LinkRes.Add('INPUT ('); + { add objectfiles, start with prt0 always } + if not (target_info.system in systems_internal_sysinit) then + begin + s:=FindObjectFile('prt0','',false); + LinkRes.AddFileName(maybequoted(s)); + end; + while not ObjectFiles.Empty do + begin + s:=ObjectFiles.GetFirst; + if s<>'' then + begin + { vlink doesn't use SEARCH_DIR for object files } + if UseVLink then + s:=FindObjectFile(s,'',false); + LinkRes.AddFileName(maybequoted(s)); + end; + end; + + { Write staticlibraries } + if not StaticLibFiles.Empty then + begin + { vlink doesn't need, and doesn't support GROUP } + if not UseVLink then + begin + LinkRes.Add(')'); + LinkRes.Add('GROUP('); + end; + while not StaticLibFiles.Empty do + begin + S:=StaticLibFiles.GetFirst; + LinkRes.AddFileName(maybequoted(s)); + end; + end; + + LinkRes.Add(')'); + + { Write and Close response } + linkres.writetodisk; + linkres.free; + + WriteResponseFile:=True; +end; + + +function TLinkerHuman68k.MakeHuman68kExe: boolean; +var + BinStr, + CmdStr : TCmdStr; + StripStr: string[40]; + DynLinkStr : ansistring; + GCSectionsStr : string; + FlagsStr : string; + MapStr: string; + ExeName: string; +begin + StripStr:=''; + GCSectionsStr:=''; + DynLinkStr:=''; + MapStr:=''; + FlagsStr:=''; + + if (cs_link_map in current_settings.globalswitches) then + if UseVLink then + MapStr:='-M'+maybequoted(ScriptFixFileName(current_module.mapfilename)) + else + MapStr:='-Map '+maybequoted(ScriptFixFileName(current_module.mapfilename)); + if (cs_link_strip in current_settings.globalswitches) then + StripStr:='-s'; + if rlinkpath<>'' then + DynLinkStr:='--rpath-link '+rlinkpath; + if UseVLink then + begin + if create_smartlink_sections then + GCSectionsStr:='-gc-all -sc'; + end; + + ExeName:=current_module.exefilename; + + { Call linker } + SplitBinCmd(Info.ExeCmd[1],BinStr,CmdStr); + binstr:=FindUtil(utilsprefix+BinStr); + Replace(cmdstr,'$OPT',Info.ExtraOptions); + Replace(cmdstr,'$EXE',maybequoted(ScriptFixFileName(ExeName))); + Replace(cmdstr,'$RES',maybequoted(ScriptFixFileName(outputexedir+Info.ResName))); + Replace(cmdstr,'$MAP',MapStr); + Replace(cmdstr,'$FLAGS',FlagsStr); + Replace(cmdstr,'$STRIP',StripStr); + Replace(cmdstr,'$GCSECTIONS',GCSectionsStr); + Replace(cmdstr,'$DYNLINK',DynLinkStr); + + MakeHuman68kExe:=DoExec(BinStr,CmdStr,true,false); +end; + + +function TLinkerHuman68k.MakeExecutable:boolean; +var + success : boolean; + bootfile : TScript; + ExeName: String; +begin + if not(cs_link_nolink in current_settings.globalswitches) then + Message1(exec_i_linking,current_module.exefilename); + + { Write used files and libraries } + WriteResponseFile(false); + + success:=MakeHuman68kExe; + + { Remove ReponseFile } + if (success) and not(cs_link_nolink in current_settings.globalswitches) then + DeleteFile(outputexedir+Info.ResName); + + MakeExecutable:=success; { otherwise a recursive call to link method } +end; + + + + +{***************************************************************************** + Initialize +*****************************************************************************} + +initialization + RegisterLinker(ld_human68k,TLinkerHuman68k); + RegisterTarget(system_m68k_human68k_info); +end. diff --git a/compiler/utils/ppuutils/ppudump.pp b/compiler/utils/ppuutils/ppudump.pp index c5605b2800..fcfc06fa49 100644 --- a/compiler/utils/ppuutils/ppudump.pp +++ b/compiler/utils/ppuutils/ppudump.pp @@ -247,7 +247,8 @@ const { 118 } 'Linux-MIPS64el', { 119 } 'FreeRTos-RiscV32', { 120 } 'Linux-LoongArch64', - { 121 } 'iPhoneSim-AArch64' + { 121 } 'iPhoneSim-AArch64', + { 122 ] 'Human68k-m68k' ); const