瀏覽代碼

+ implement initial compiler support for Win64 on Aarch64

git-svn-id: trunk@44914 -
svenbarth 5 年之前
父節點
當前提交
3af74d2fd2

+ 3 - 0
compiler/aarch64/cputarg.pas

@@ -44,6 +44,9 @@ implementation
     {$ifndef NOTARGETANDROID}
       ,t_android
     {$endif}
+    {$ifndef NOTARGETWIN64}
+      ,t_win
+    {$endif}
 
 {**************************************
              Assemblers

+ 1 - 0
compiler/gendef.pas

@@ -126,6 +126,7 @@ begin
       end;
     system_i386_win32,
     system_x86_64_win64,
+    system_aarch64_win64,
     obsolete_system_ia64_win64,
     system_arm_wince,
     system_i386_wince,

+ 23 - 10
compiler/ogcoff.pas

@@ -287,6 +287,11 @@ interface
        COFF_OPT_MAGIC   = $20b;
        TLSDIR_SIZE      = $28;
 {$endif x86_64}
+{$ifdef aarch64}
+       COFF_MAGIC       = $AA64;
+       COFF_OPT_MAGIC   = $20b;
+       TLSDIR_SIZE      = $28;
+{$endif aarch64}
        COFF_BIG_OBJ_MAGIC: array[0..15] of byte = ($C7, $A1, $BA, $D1, $EE, $BA, $A9, $4B, $AF, $20, $FA, $F6, $6A, $A4, $DC, $B8);
        COFF_BIG_OBJ_VERSION = 2;
 
@@ -1739,12 +1744,12 @@ const pemagic : array[0..3] of byte = (
                header.syms:=symidx;
                if win32 then
                  begin
-{$ifndef x86_64}
+{$ifndef cpu64bitaddr}
                    header.flag:=PE_FILE_32BIT_MACHINE or
                                 PE_FILE_LINE_NUMS_STRIPPED or PE_FILE_LOCAL_SYMS_STRIPPED;
-{$else x86_64}
+{$else cpu64bitaddr}
                    header.flag:=PE_FILE_LINE_NUMS_STRIPPED or PE_FILE_LOCAL_SYMS_STRIPPED;
-{$endif x86_64}
+{$endif cpu64bitaddr}
                  end
                else
                  header.flag:=COFF_FLAG_AR32WR or COFF_FLAG_NOLINES or COFF_FLAG_NOLSYMS;
@@ -2405,7 +2410,7 @@ const pemagic : array[0..3] of byte = (
       begin
         inherited create;
         win32:=awin32;
-        if target_info.system in [system_x86_64_win64] then
+        if target_info.system in [system_x86_64_win64,system_aarch64_win64] then
           MaxMemPos:=$FFFFFFFF
         else
           if target_info.system in systems_wince then
@@ -2743,7 +2748,7 @@ const pemagic : array[0..3] of byte = (
         if win32 then
           begin
             header.flag:=PE_FILE_EXECUTABLE_IMAGE or PE_FILE_LINE_NUMS_STRIPPED;
-            if target_info.system in [system_x86_64_win64] then
+            if target_info.system in [system_x86_64_win64,system_aarch64_win64] then
               header.flag:=header.flag or PE_FILE_LARGE_ADDRESS_AWARE
             else
               header.flag:=header.flag or PE_FILE_32BIT_MACHINE;
@@ -3022,16 +3027,22 @@ const pemagic : array[0..3] of byte = (
 
         function AddImport(const afuncname,amangledname:string; AOrdNr:longint;isvar:boolean):TObjSymbol;
         const
-  {$ifdef arm}
+  {$if defined(arm)}
           jmpopcode : array[0..7] of byte = (
             $00,$c0,$9f,$e5,    // ldr ip, [pc, #0]
             $00,$f0,$9c,$e5     // ldr pc, [ip]
           );
-  {$else arm}
+  {$elseif defined(aarch64)}
+          jmpopcode : array[0..11] of byte = (
+            $70,$00,$00,$58,    // ldr ip0, .+12
+            $10,$02,$40,$F9,    // ldr ip0, [ip0]
+            $00,$02,$1F,$D6     // br ip0
+          );
+  {$else}
           jmpopcode : array[0..1] of byte = (
             $ff,$25
           );
-  {$endif arm}
+  {$endif}
           nopopcodes : array[0..1] of byte = (
             $90,$90
           );
@@ -3086,11 +3097,13 @@ const pemagic : array[0..3] of byte = (
               textobjsection.writezeros(align_aword(textobjsection.size,16)-textobjsection.size);
               result:=internalobjdata.SymbolDefine('_'+amangledname,AB_GLOBAL,AT_FUNCTION);
               textobjsection.write(jmpopcode,sizeof(jmpopcode));
-{$ifdef x86_64}
+{$if defined(x86_64)}
               textobjsection.writereloc_internal(idata5objsection,idata5objsection.size,4,RELOC_RELATIVE);
+{$elseif defined(aarch64)}
+              textobjsection.writereloc_internal(idata5objsection,idata5objsection.size,8,RELOC_ABSOLUTE);
 {$else}
               textobjsection.writereloc_internal(idata5objsection,idata5objsection.size,4,RELOC_ABSOLUTE32);
-{$endif x86_64}
+{$endif x86_64 or aarch64}
 
               textobjsection.write(nopopcodes,align(textobjsection.size,qword(sizeof(nopopcodes)))-textobjsection.size);
             end;

+ 1 - 1
compiler/options.pas

@@ -4608,7 +4608,7 @@ begin
 
   { Section smartlinking conflicts with import sections on Windows }
   if GenerateImportSection and
-     (target_info.system in [system_i386_win32,system_x86_64_win64]) then
+     (target_info.system in [system_i386_win32,system_x86_64_win64,system_aarch64_win64]) then
     exclude(target_info.flags,tf_smartlink_sections);
 
   if not option.LinkTypeSetExplicitly then

+ 2 - 1
compiler/systems.inc

@@ -194,7 +194,8 @@
              system_xtensa_embedded,    { 103 }
              system_xtensa_freertos,    { 104 }
              system_xtensa_linux,       { 105 }
-             system_arm_freertos        { 106 }
+             system_arm_freertos,       { 106 }
+             system_aarch64_win64       { 107 }
        );
 
      type

+ 15 - 7
compiler/systems.pas

@@ -276,11 +276,11 @@ interface
        systems_aix = [system_powerpc_aix,system_powerpc64_aix];
 
        { all real windows systems, no cripple ones like win16, wince, wdosx et. al. }
-       systems_windows = [system_i386_win32,system_x86_64_win64];
+       systems_windows = [system_i386_win32,system_x86_64_win64,system_aarch64_win64];
 
        { all windows systems }
-       systems_all_windows = [system_i386_win32,system_x86_64_win64,
-                             system_arm_wince,system_i386_wince,
+       systems_all_windows = systems_windows+
+                             [system_arm_wince,system_i386_wince,
                              system_i8086_win16];
 
        { all darwin systems }
@@ -356,13 +356,16 @@ interface
                                          system_i386_netwlibc,
                                          system_arm_wince,
                                          system_x86_64_win64,
-                                         system_i8086_win16]+systems_linux+systems_android;
+                                         system_i8086_win16,
+                                         system_aarch64_win64]+systems_linux+systems_android;
 
        { all systems that reference symbols in other binaries using indirect imports }
        systems_indirect_var_imports = systems_all_windows+[system_i386_nativent];
 
        { all systems that support indirect entry information }
-       systems_indirect_entry_information = systems_darwin+[system_i386_win32,system_x86_64_win64,system_x86_64_linux];
+       systems_indirect_entry_information = systems_darwin+
+                                            [system_i386_win32,system_x86_64_win64,system_x86_64_linux,
+                                            system_aarch64_win64];
 
        { all systems for which weak linking has been tested/is supported }
        systems_weak_linking = systems_darwin + systems_solaris + systems_linux + systems_android + systems_openbsd + systems_freebsd;
@@ -373,13 +376,14 @@ interface
                                    system_m68k_atari,system_m68k_palmos,
                                    system_i386_haiku,system_x86_64_haiku,
                                    system_i386_openbsd,system_x86_64_openbsd,
-                                   system_riscv32_linux,system_riscv64_linux
+                                   system_riscv32_linux,system_riscv64_linux,
+                                   system_aarch64_win64
                                   ]+systems_darwin+systems_amigalike;
 
        { all systems that use the PE+ header in the PE/COFF file
          Note: this is here and not in ogcoff, because it's required in other
                units as well }
-       systems_peoptplus = [system_x86_64_win64];
+       systems_peoptplus = [system_x86_64_win64,system_aarch64_win64];
 
        { all systems that use garbage collection for reference-counted types }
        systems_garbage_collected_managed_types = [
@@ -1113,6 +1117,10 @@ begin
       {$define default_target_set}
       default_target(system_aarch64_android);
     {$endif android}
+    {$ifdef windows}
+      {$define default_target_set}
+      default_target(system_aarch64_win64);
+    {$endif}
     {$ifndef default_target_set}
       default_target(system_aarch64_linux);
       {$define default_target_set}

+ 77 - 0
compiler/systems/i_win.pas

@@ -309,6 +309,77 @@ unit i_win;
             llvmdatalayout : 'todo';
           );
 
+       system_aarch64_win64_info : tsysteminfo =
+          (
+            system       : system_aarch64_win64;
+            name         : 'Win64 for Aarch64';
+            shortname    : 'Win64';
+            flags        : [tf_files_case_aware,tf_has_dllscanner,
+                            tf_smartlink_sections,
+                            tf_winlikewidestring,tf_no_pic_supported,
+                            tf_dwarf_only_local_labels,
+                            tf_no_generic_stackcheck,tf_has_winlike_resources,
+                            tf_safecall_exceptions,tf_no_backquote_support,tf_supports_hidden_symbols];
+            cpu          : cpu_aarch64;
+            unit_env     : 'WIN64UNITS';
+            extradefines : 'MSWINDOWS;WINDOWS';
+            exeext       : '.exe';
+            defext       : '.def';
+            scriptext    : '.bat';
+            smartext     : '.sl';
+            unitext      : '.ppu';
+            unitlibext   : '.ppl';
+            asmext       : '.s';
+            objext       : '.o';
+            resext       : '.res';
+            resobjext    : '.obj';
+            sharedlibext : '.dll';
+            staticlibext : '.a';
+            staticlibprefix : 'libp';
+            sharedlibprefix : '';
+            sharedClibext : '.dll';
+            staticClibext : '.a';
+            staticClibprefix : 'lib';
+            sharedClibprefix : '';
+            importlibprefix : 'libimp';
+            importlibext : '.a';
+            Cprefix      : '';
+            newline      : #13#10;
+            dirsep       : '\';
+            assem        : as_clang_gas;
+            assemextern  : as_clang_gas;
+            link         : ld_int_windows;
+            linkextern   : ld_windows;
+            ar           : ar_gnu_ar;
+            res          : res_gnu_windres;
+            dbg          : dbg_dwarf2;
+            script       : script_dos;
+            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    : 16*1024*1024;
+            stackalign   : 16;
+            abi          : abi_default;
+            llvmdatalayout : 'e-p:64:64:64-i1:8:8-i8:8:8-i16:16:16-i32:32:32-i64:64:64-f32:32:32-f64:64:64-v64:64:64-v128:128:128-a0:0:64-n32:64-S128'
+          );
+
 
   implementation
 
@@ -337,4 +408,10 @@ initialization
     set_source_info(system_arm_wince_info);
   {$endif WINCE}
 {$endif CPUARM}
+
+{$ifdef CPUAARCH64}
+  {$ifdef WIN64}
+    set_source_info(system_aarch64_win64_info);
+  {$endif WIN64}
+{$endif CPUAARCH64}
 end.

+ 28 - 12
compiler/systems/t_win.pas

@@ -151,7 +151,7 @@ implementation
           else
             linker.sysinitunit:='sysinitpas';
         end
-      else if target_info.system=system_x86_64_win64 then
+      else if target_info.system in [system_x86_64_win64,system_aarch64_win64] then
         linker.sysinitunit:='sysinit';
     end;
 
@@ -270,22 +270,26 @@ implementation
 
         procedure AddImport(const afuncname,mangledname:string;ordnr:longint;isvar:boolean);
         const
-{$ifdef x86_64}
+{$if defined(x86_64)}
           jmpopcode : array[0..1] of byte = (
             $ff,$25             // jmp qword [rip + offset32]
           );
-{$else x86_64}
-  {$ifdef arm}
+{$elseif defined(arm)}
           jmpopcode : array[0..7] of byte = (
             $00,$c0,$9f,$e5,    // ldr ip, [pc, #0]
             $00,$f0,$9c,$e5     // ldr pc, [ip]
           );
-  {$else arm}
+{$elseif defined(aarch64)}
+          jmpopcode : array[0..11] of byte = (
+            $70,$00,$00,$58,    // ldr ip0, .+12
+            $10,$02,$40,$F9,    // ldr ip0, [ip0]
+            $00,$02,$1F,$D6     // br ip0
+          );
+{$elseif defined(i386)}
           jmpopcode : array[0..1] of byte = (
             $ff,$25
           );
-  {$endif arm}
-{$endif x86_64}
+{$endif}
           nopopcodes : array[0..1] of byte = (
             $90,$90
           );
@@ -378,11 +382,13 @@ implementation
               else
                 implabel:=objdata.SymbolDefine(basedllname+'_index_'+tostr(ordnr),AB_GLOBAL,AT_FUNCTION);
               objdata.writebytes(jmpopcode,sizeof(jmpopcode));
-{$ifdef x86_64}
+{$if defined(x86_64)}
               objdata.writereloc(0,sizeof(longint),idata5label,RELOC_RELATIVE);
+{$elseif defined(aarch64)}
+              objdata.writereloc(0,sizeof(aint),idata5label,RELOC_ABSOLUTE);
 {$else}
               objdata.writereloc(0,sizeof(longint),idata5label,RELOC_ABSOLUTE32);
-{$endif x86_64}
+{$endif x86_64 or aarch64}
               objdata.writebytes(nopopcodes,align(objdata.CurrObjSec.size,qword(sizeof(nopopcodes)))-objdata.CurrObjSec.size);
             end;
           ObjOutput.exportsymbol(implabel);
@@ -524,7 +530,7 @@ implementation
                     else
                       current_asmdata.asmlists[al_imports].concat(Tai_symbol.Createname_global(ExtractFileName(ImportLibrary.Name)+'_index_'+tostr(ImportSymbol.ordnr),AT_FUNCTION,0,voidcodepointertype));
                     current_asmdata.asmlists[al_imports].concat(tai_function_name.create(''));
-                  {$ifdef ARM}
+                  {$if defined(ARM)}
                     reference_reset_symbol(href,l5,0,sizeof(pint),[]);
                     current_asmdata.asmlists[al_imports].concat(Taicpu.op_reg_ref(A_LDR,NR_R12,href));
                     reference_reset_base(href,NR_R12,0,ctempposinvalid,sizeof(pint),[]);
@@ -532,7 +538,10 @@ implementation
                     current_asmdata.asmlists[al_imports].concat(Tai_label.Create(l5));
                     reference_reset_symbol(href,l4,0,sizeof(pint),[]);
                     current_asmdata.asmlists[al_imports].concat(tai_const.create_sym_offset(href.symbol,href.offset));
-                  {$else ARM}
+                  {$elseif defined(AARCH64)}
+                    { ToDo }
+                    internalerror(2020033001);
+                  {$else X86}
                     reference_reset_symbol(href,l4,0,sizeof(pint),[]);
 {$ifdef X86_64}
                     href.base:=NR_RIP;
@@ -540,7 +549,7 @@ implementation
 
                     current_asmdata.asmlists[al_imports].concat(Taicpu.Op_ref(A_JMP,S_NO,href));
                     current_asmdata.asmlists[al_imports].concat(Tai_align.Create_op(4,$90));
-                  {$endif ARM}
+                  {$endif X86}
                     { add jump field to al_imports }
                     new_section(current_asmdata.asmlists[al_imports],sec_idata5,'',0);
                     if (cs_debuginfo in current_settings.moduleswitches) then
@@ -1859,4 +1868,11 @@ initialization
   RegisterRes(res_gnu_windres_info,TWinLikeResourceFile);
   RegisterTarget(system_arm_wince_info);
 {$endif arm}
+{$ifdef aarch64}
+  RegisterImport(system_aarch64_win64,TImportLibWin);
+  RegisterExport(system_aarch64_win64,TExportLibWin);
+  // ToDo?
+  RegisterRes(res_gnu_windres_info,TWinLikeResourceFile);
+  RegisterTarget(system_aarch64_win64_info);
+{$endif aarch64}
 end.

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

@@ -224,7 +224,8 @@ const
   { 103 } 'Embedded-Xtensa',
   { 104 } 'FreeRTos-Xtensa',
   { 105 } 'Linux-Xtensa',
-  { 106 } 'FreeRTos-arm'
+  { 106 } 'FreeRTos-arm',
+  { 107 } 'Win64-AArch64'
   );
 
 const