Browse Source

+ tf_init_final_units_by_calls
* arm-embedded generates direct calls for unit init/final now as well

git-svn-id: trunk@43771 -

florian 5 năm trước cách đây
mục cha
commit
a20209e691

+ 89 - 3
compiler/arm/narmutil.pas

@@ -26,11 +26,12 @@ unit narmutil;
 interface
 interface
 
 
   uses
   uses
-    ngenutil;
+    cclasses,ngenutil;
 
 
   type
   type
     tarmnodeutils = class(tnodeutils)
     tarmnodeutils = class(tnodeutils)
       class procedure InsertObjectInfo; override;
       class procedure InsertObjectInfo; override;
+      class procedure insert_init_final_table(entries: tfplist); override;
     end;
     end;
 
 
 
 
@@ -40,8 +41,10 @@ interface
       verbose,
       verbose,
       systems,
       systems,
       globals,
       globals,
-      cpuinfo,
-      aasmdata,aasmtai;
+      cpuinfo,cpubase,
+      cgbase,cgutils,
+      aasmbase,aasmdata,aasmtai,aasmcpu,
+      symdef;
 
 
     const
     const
       Tag_File = 1;
       Tag_File = 1;
@@ -234,6 +237,89 @@ interface
           end;
           end;
       end;
       end;
 
 
+    class procedure tarmnodeutils.insert_init_final_table(entries:tfplist);
+
+      procedure genentry(list : TAsmList);
+        var
+          ref: treference;
+        begin
+          if GenerateThumbCode then
+            list.concat(taicpu.op_regset(A_PUSH,R_INTREGISTER,R_SUBWHOLE,[RS_R14]))
+          else
+            begin
+              reference_reset(ref,4,[]);
+              ref.index:=NR_STACK_POINTER_REG;
+              ref.addressmode:=AM_PREINDEXED;
+              list.concat(setoppostfix(taicpu.op_ref_regset(A_STM,ref,R_INTREGISTER,R_SUBWHOLE,[RS_R14]),PF_FD));
+            end;
+        end;
+
+      procedure genexit(list : TAsmList);
+        var
+          ref: treference;
+        begin
+          if GenerateThumbCode then
+            list.concat(taicpu.op_regset(A_POP,R_INTREGISTER,R_SUBWHOLE,[RS_R15]))
+          else
+            begin
+              reference_reset(ref,4,[]);
+              ref.index:=NR_STACK_POINTER_REG;
+              ref.addressmode:=AM_PREINDEXED;
+              list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,R_INTREGISTER,R_SUBWHOLE,[RS_R15]),PF_FD));
+            end;
+        end;
+
+      var
+        initList, finalList, header: TAsmList;
+        entry : pinitfinalentry;
+        i : longint;
+      begin
+        if not(tf_init_final_units_by_calls in target_info.flags) then
+          begin
+            inherited insert_init_final_table(entries);
+            exit;
+          end;
+        initList:=TAsmList.create;
+        finalList:=TAsmList.create;
+
+        genentry(finalList);
+        genentry(initList);
+
+        for i:=0 to entries.count-1 do
+          begin
+            entry:=pinitfinalentry(entries[i]);
+            if entry^.finifunc<>'' then
+              finalList.Concat(taicpu.op_sym(A_BL,current_asmdata.RefAsmSymbol(entry^.finifunc,AT_FUNCTION)));
+            if entry^.initfunc<>'' then
+              initList.Concat(taicpu.op_sym(A_BL,current_asmdata.RefAsmSymbol(entry^.initfunc,AT_FUNCTION)));
+          end;
+
+        genexit(finalList);
+        genexit(initList);
+
+        header:=TAsmList.create;
+        new_section(header, sec_code, 'FPC_INIT_FUNC_TABLE', 1);
+        header.concat(tai_symbol.Createname_global('FPC_INIT_FUNC_TABLE',AT_FUNCTION,0,voidcodepointertype));
+
+        initList.insertList(header);
+        header.free;
+
+        current_asmdata.AsmLists[al_procedures].concatList(initList);
+
+        header:=TAsmList.create;
+        new_section(header, sec_code, 'FPC_FINALIZE_FUNC_TABLE', 1);
+        header.concat(tai_symbol.Createname_global('FPC_FINALIZE_FUNC_TABLE',AT_FUNCTION,0,voidcodepointertype));
+
+        finalList.insertList(header);
+        header.free;
+
+        current_asmdata.AsmLists[al_procedures].concatList(finalList);
+
+        initList.Free;
+        finalList.Free;
+
+        inherited insert_init_final_table(entries);
+      end;
 
 
   begin
   begin
     cnodeutils:=tarmnodeutils;
     cnodeutils:=tarmnodeutils;

+ 6 - 5
compiler/hlcgobj.pas

@@ -4761,11 +4761,12 @@ implementation
        begin
        begin
          { initialize units }
          { initialize units }
          if not(current_module.islibrary) then
          if not(current_module.islibrary) then
-{$ifdef AVR}
-           cg.a_call_name(list,'FPC_INIT_FUNC_TABLE',false)
-{$else AVR}
-           g_call_system_proc(list,'fpc_initializeunits',[],nil).resetiftemp
-{$endif AVR}
+           begin
+             if tf_init_final_units_by_calls in target_info.flags then
+               cg.a_call_name(list,'FPC_INIT_FUNC_TABLE',false)
+             else
+               g_call_system_proc(list,'fpc_initializeunits',[],nil).resetiftemp;
+           end
          else
          else
            g_call_system_proc(list,'fpc_libinitializeunits',[],nil).resetiftemp;
            g_call_system_proc(list,'fpc_libinitializeunits',[],nil).resetiftemp;
        end;
        end;

+ 6 - 0
compiler/options.pas

@@ -3218,6 +3218,12 @@ begin
     else
     else
       undef_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
       undef_system_macro('FPC_REQUIRES_PROPER_ALIGNMENT');
 
 
+  if (tf_init_final_units_by_calls in target_info.flags) then
+    if def then
+      def_system_macro('FPC_INIT_FINAL_UNITS_BY_CALLS')
+    else
+      undef_system_macro('FPC_INIT_FINAL_UNITS_BY_CALLS');
+
   if source_info.system<>target_info.system then
   if source_info.system<>target_info.system then
     if def then
     if def then
       def_system_macro('FPC_CROSSCOMPILING')
       def_system_macro('FPC_CROSSCOMPILING')

+ 5 - 1
compiler/systems.pas

@@ -173,7 +173,11 @@ interface
             { supports symbol order file (to ensure symbols in vectorised sections are kept in the correct order) }
             { supports symbol order file (to ensure symbols in vectorised sections are kept in the correct order) }
             tf_supports_symbolorderfile,
             tf_supports_symbolorderfile,
             { supports hidden/private extern symbols: visible across object files, but local/private in exe/library }
             { supports hidden/private extern symbols: visible across object files, but local/private in exe/library }
-            tf_supports_hidden_symbols
+            tf_supports_hidden_symbols,
+            { units are initialized by direct calls and not table driven,
+              in particular for a small amount of units, this results in smaller
+              executables }
+            tf_init_final_units_by_calls
        );
        );
 
 
        psysteminfo = ^tsysteminfo;
        psysteminfo = ^tsysteminfo;

+ 2 - 2
compiler/systems/i_embed.pas

@@ -41,7 +41,7 @@ unit i_embed;
             name         : 'Embedded';
             name         : 'Embedded';
             shortname    : 'embedded';
             shortname    : 'embedded';
             flags        : [tf_needs_symbol_size,tf_files_case_sensitive,tf_requires_proper_alignment,
             flags        : [tf_needs_symbol_size,tf_files_case_sensitive,tf_requires_proper_alignment,
-                            tf_smartlink_sections];
+                            tf_smartlink_sections,tf_init_final_units_by_calls];
             cpu          : cpu_arm;
             cpu          : cpu_arm;
             unit_env     : '';
             unit_env     : '';
             extradefines : '';
             extradefines : '';
@@ -108,7 +108,7 @@ unit i_embed;
             name         : 'Embedded';
             name         : 'Embedded';
             shortname    : 'embedded';
             shortname    : 'embedded';
             flags        : [tf_needs_symbol_size,tf_files_case_sensitive,
             flags        : [tf_needs_symbol_size,tf_files_case_sensitive,
-                            tf_smartlink_sections];
+                            tf_smartlink_sections,tf_init_final_units_by_calls];
             cpu          : cpu_avr;
             cpu          : cpu_avr;
             unit_env     : '';
             unit_env     : '';
             extradefines : '';
             extradefines : '';

+ 3 - 3
rtl/inc/system.inc

@@ -1044,10 +1044,10 @@ begin
 end;
 end;
 
 
 
 
-{$ifdef CPUAVR}
+{$ifdef FPC_INIT_FINAL_UNITS_BY_CALLS}
 procedure FinalizeUnits; external name 'FPC_FINALIZE_FUNC_TABLE';
 procedure FinalizeUnits; external name 'FPC_FINALIZE_FUNC_TABLE';
 
 
-{$else CPUAVR}
+{$else FPC_INIT_FINAL_UNITS_BY_CALLS}
 procedure FinalizeUnits;[public,alias:'FPC_FINALIZEUNITS'];
 procedure FinalizeUnits;[public,alias:'FPC_FINALIZEUNITS'];
 begin
 begin
 {$ifdef FPC_HAS_INDIRECT_ENTRY_INFORMATION}
 {$ifdef FPC_HAS_INDIRECT_ENTRY_INFORMATION}
@@ -1066,7 +1066,7 @@ begin
       end;
       end;
    end;
    end;
 end;
 end;
-{$endif CPUAVR}
+{$endif FPC_INIT_FINAL_UNITS_BY_CALLS}
 
 
 {*****************************************************************************
 {*****************************************************************************
                           Error / Exit / ExitProc
                           Error / Exit / ExitProc