ソースを参照

m68k: initial compiler changes for Human68k (Sharp X68000) support

Karoly Balogh 1 年間 前
コミット
4a1db1dc79

+ 2 - 1
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

+ 3 - 0
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}

+ 3 - 2
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;

+ 3 - 0
compiler/m68k/cputarg.pas

@@ -56,6 +56,9 @@ implementation
     {$ifndef NOTARGETSINCLAIRQL}
       ,t_sinclairql
     {$endif}
+    {$ifndef NOTARGETHUMAN68K}
+      ,t_human68k
+    {$endif}
     {$ifndef NOTARGETEMBEDDED}
       ,t_embed
     {$endif}

+ 1 - 0
compiler/msg/errore.msg

@@ -4282,6 +4282,7 @@ F*2P<x>_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)

+ 6 - 3
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;

+ 4 - 2
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

+ 108 - 0
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.

+ 254 - 0
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.

+ 2 - 1
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