Răsfoiți Sursa

Add support for ram-less AVR chips and simultanously optimize flash/ram size the initfinal calling sequence.

git-svn-id: trunk@32448 -
Jeppe Johansen 9 ani în urmă
părinte
comite
5ec4d38231

+ 1 - 0
.gitattributes

@@ -121,6 +121,7 @@ compiler/avr/itcpugas.pas svneol=native#text/plain
 compiler/avr/navradd.pas svneol=native#text/plain
 compiler/avr/navradd.pas svneol=native#text/plain
 compiler/avr/navrcnv.pas svneol=native#text/plain
 compiler/avr/navrcnv.pas svneol=native#text/plain
 compiler/avr/navrmat.pas svneol=native#text/plain
 compiler/avr/navrmat.pas svneol=native#text/plain
+compiler/avr/navrutil.pas svneol=native#text/pascal
 compiler/avr/raavr.pas svneol=native#text/plain
 compiler/avr/raavr.pas svneol=native#text/plain
 compiler/avr/raavrgas.pas svneol=native#text/plain
 compiler/avr/raavrgas.pas svneol=native#text/plain
 compiler/avr/ravrcon.inc svneol=native#text/plain
 compiler/avr/ravrcon.inc svneol=native#text/plain

+ 9 - 2
compiler/avr/cgcpu.pas

@@ -402,11 +402,18 @@ unit cgcpu;
 
 
 
 
     procedure tcgavr.a_call_name(list : TAsmList;const s : string; weak: boolean);
     procedure tcgavr.a_call_name(list : TAsmList;const s : string; weak: boolean);
+      var
+        sym: TAsmSymbol;
       begin
       begin
+        if weak then
+          sym:=current_asmdata.WeakRefAsmSymbol(s)
+        else
+          sym:=current_asmdata.RefAsmSymbol(s);
+
         if CPUAVR_HAS_JMP_CALL in cpu_capabilities[current_settings.cputype] then
         if CPUAVR_HAS_JMP_CALL in cpu_capabilities[current_settings.cputype] then
-          list.concat(taicpu.op_sym(A_CALL,current_asmdata.RefAsmSymbol(s)))
+          list.concat(taicpu.op_sym(A_CALL,sym))
         else
         else
-          list.concat(taicpu.op_sym(A_RCALL,current_asmdata.RefAsmSymbol(s)));
+          list.concat(taicpu.op_sym(A_RCALL,sym));
 
 
         include(current_procinfo.flags,pi_do_call);
         include(current_procinfo.flags,pi_do_call);
       end;
       end;

+ 2 - 1
compiler/avr/cpunode.pas

@@ -36,7 +36,8 @@ unit cpunode;
        }
        }
        ,navradd
        ,navradd
        ,navrmat
        ,navrmat
-       ,navrcnv,
+       ,navrcnv
+       ,navrutil,
        { symtable }
        { symtable }
        symcpu
        symcpu
        ;
        ;

+ 198 - 0
compiler/avr/navrutil.pas

@@ -0,0 +1,198 @@
+{
+    Copyright (c) 2015 by Jeppe Johansen
+
+    AVR version of some node tree helper routines
+
+    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 navrutil;
+
+{$i fpcdefs.inc}
+
+interface
+
+  uses
+    node,nbas,
+    ngenutil,
+    symtype,symconst,symsym,symdef;
+
+
+  type
+    tavrnodeutils = class(tnodeutils)
+      class procedure InsertInitFinalTable; override;
+    end;
+
+implementation
+
+    uses
+      verbose,cutils,globtype,globals,constexp,fmodule,
+      cclasses,
+      aasmdata,aasmtai,aasmcpu,aasmcnst,aasmbase,
+      cpubase,
+      symbase,symcpu,symtable,defutil,
+      ncnv,ncon,ninl,ncal,nld,nmem,
+      systems,
+      CPUInfo,
+      ppu,
+      pass_1;
+
+
+  procedure AddToStructInits(p:TObject;arg:pointer);
+    var
+      StructList: TFPList absolute arg;
+    begin
+      if (tdef(p).typ in [objectdef,recorddef]) and
+         not (df_generic in tdef(p).defoptions) then
+        begin
+          { first add the class... }
+          if ([oo_has_class_constructor,oo_has_class_destructor] * tabstractrecorddef(p).objectoptions <> []) then
+            StructList.Add(p);
+          { ... and then also add all subclasses }
+          tabstractrecorddef(p).symtable.deflist.foreachcall(@AddToStructInits,arg);
+        end;
+    end;
+
+
+  class procedure tavrnodeutils.InsertInitFinalTable;
+    var
+      hp : tused_unit;
+      op: TAsmOp;
+      initCount, finalCount: longint;
+
+      procedure write_struct_inits(InitList, FinalizeList: TAsmList; u: tmodule);
+        var
+          i: integer;
+          structlist: TFPList;
+          pd: tprocdef;
+        begin
+          structlist := TFPList.Create;
+          if assigned(u.globalsymtable) then
+            u.globalsymtable.DefList.ForEachCall(@AddToStructInits,structlist);
+          u.localsymtable.DefList.ForEachCall(@AddToStructInits,structlist);
+          { write structures }
+          for i:=0 to structlist.Count-1 do
+          begin
+            pd:=tabstractrecorddef(structlist[i]).find_procdef_bytype(potype_class_constructor);
+            if assigned(pd) then
+              begin
+                InitList.Concat(taicpu.op_sym(op,current_asmdata.RefAsmSymbol(pd.mangledname)));
+                inc(initCount);
+              end;
+
+            pd := tabstractrecorddef(structlist[i]).find_procdef_bytype(potype_class_destructor);
+            if assigned(pd) then
+              begin
+                FinalizeList.Concat(taicpu.op_sym(op,current_asmdata.RefAsmSymbol(pd.mangledname)));
+                inc(finalCount);
+              end;
+          end;
+          structlist.free;
+        end;
+
+    var
+      initList, finalList, header: TAsmList;
+    begin
+      initList:=TAsmList.create;
+      finalList:=TAsmList.create;
+
+      initCount:=0;
+      finalCount:=0;
+
+      if CPUAVR_HAS_JMP_CALL in cpu_capabilities[current_settings.cputype] then
+        op:=A_CALL
+      else
+        op:=A_RCALL;
+
+      hp:=tused_unit(usedunits.first);
+      while assigned(hp) do
+        begin
+          if (hp.u.flags and uf_classinits) <> 0 then
+            write_struct_inits(initList, finalList, hp.u);
+
+          if (hp.u.flags and (uf_init or uf_finalize))<>0 then
+            begin
+              if (hp.u.flags and uf_init)<>0 then
+                begin
+                  initList.Concat(taicpu.op_sym(op,current_asmdata.RefAsmSymbol(make_mangledname('INIT$',hp.u.globalsymtable,''))));
+                  inc(initCount);
+                end;
+
+              if (hp.u.flags and uf_finalize)<>0 then
+                begin
+                  finalList.Concat(taicpu.op_sym(op,current_asmdata.RefAsmSymbol(make_mangledname('FINALIZE$',hp.u.globalsymtable,''))));
+                  inc(finalCount);
+                end;
+            end;
+
+          hp:=tused_unit(hp.next);
+        end;
+
+      { insert class constructors/destructor of the program }
+      if (current_module.flags and uf_classinits) <> 0 then
+        write_struct_inits(initList, finalList, current_module);
+
+      { Insert initialization/finalization of the program }
+      if (current_module.flags and (uf_init or uf_finalize))<>0 then
+        begin
+          if (current_module.flags and uf_init)<>0 then
+            begin
+              initList.Concat(taicpu.op_sym(op,current_asmdata.RefAsmSymbol(make_mangledname('INIT$',current_module.localsymtable,''))));
+              inc(initCount);
+            end;
+
+          if (current_module.flags and uf_finalize)<>0 then
+            begin
+              finalList.Concat(taicpu.op_sym(op,current_asmdata.RefAsmSymbol(make_mangledname('FINALIZE$',current_module.localsymtable,''))));
+              inc(finalCount);
+            end;
+        end;
+
+      initList.Concat(taicpu.op_none(A_RET));
+      finalList.Concat(taicpu.op_none(A_RET));
+
+      begin
+        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));
+
+        initList.insertList(header);
+        header.free;
+
+        current_asmdata.AsmLists[al_procedures].concatList(initList);
+      end;
+
+      begin
+        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));
+
+        finalList.insertList(header);
+        header.free;
+
+        current_asmdata.AsmLists[al_procedures].concatList(finalList);
+      end;
+
+      initList.Free;
+      finalList.Free;
+
+      inherited InsertInitFinalTable;
+    end;
+
+begin
+  cnodeutils:=tavrnodeutils;
+end.
+

+ 4 - 0
compiler/hlcgobj.pas

@@ -4605,7 +4605,11 @@ 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)
            g_call_system_proc(list,'fpc_initializeunits',[],nil)
+{$endif AVR}
          else
          else
            g_call_system_proc(list,'fpc_libinitializeunits',[],nil);
            g_call_system_proc(list,'fpc_libinitializeunits',[],nil);
        end;
        end;

+ 1 - 7
rtl/avr/avr.inc

@@ -17,17 +17,11 @@
 
 
 {$asmmode gas}
 {$asmmode gas}
 
 
-Procedure SysInitFPU;{$ifdef SYSTEMINLINE}inline;{$endif}
+procedure fpc_cpuinit;{$ifdef SYSTEMINLINE}inline;{$endif}
   begin
   begin
   end;
   end;
 
 
 
 
-procedure fpc_cpuinit;
-  begin
-    SysInitFPU;
-  end;
-
-
 {$define FPC_SYSTEM_HAS_MOVE}
 {$define FPC_SYSTEM_HAS_MOVE}
 procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE'];
 procedure Move(const source;var dest;count:SizeInt);[public, alias: 'FPC_MOVE'];
 var
 var

+ 2 - 9
rtl/embedded/system.pp

@@ -163,16 +163,9 @@ const calculated_cmdline:Pchar=nil;
                        Misc. System Dependent Functions
                        Misc. System Dependent Functions
 *****************************************************************************}
 *****************************************************************************}
 
 
-procedure haltproc(e:longint);cdecl;external name '_haltproc';
+procedure haltproc;cdecl;external name '_haltproc';
 
 
-procedure System_exit;noreturn;
-begin
-{$ifdef FPC_HAS_FEATURE_EXITCODE}
-  haltproc(ExitCode);
-{$else FPC_HAS_FEATURE_EXITCODE}
-  haltproc(0);
-{$endif FPC_HAS_FEATURE_EXITCODE}
-End;
+procedure System_exit;noreturn;external name '_haltproc';
 
 
 
 
 {$ifdef FPC_HAS_FEATURE_PROCESSES}
 {$ifdef FPC_HAS_FEATURE_PROCESSES}

+ 7 - 0
rtl/inc/system.inc

@@ -915,6 +915,10 @@ begin
 end;
 end;
 
 
 
 
+{$ifdef CPUAVR}
+procedure FinalizeUnits; external name 'FPC_FINALIZE_FUNC_TABLE';
+
+{$else CPUAVR}
 procedure FinalizeUnits;[public,alias:'FPC_FINALIZEUNITS'];
 procedure FinalizeUnits;[public,alias:'FPC_FINALIZEUNITS'];
 begin
 begin
 {$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
 {$ifdef FPC_HAS_INDIRECT_MAIN_INFORMATION}
@@ -933,6 +937,7 @@ begin
       end;
       end;
    end;
    end;
 end;
 end;
+{$endif CPUAVR}
 
 
 {*****************************************************************************
 {*****************************************************************************
                           Error / Exit / ExitProc
                           Error / Exit / ExitProc
@@ -974,6 +979,7 @@ Begin
 {$ifdef SYSTEMDEBUG}
 {$ifdef SYSTEMDEBUG}
   writeln('InternalExit');
   writeln('InternalExit');
 {$endif SYSTEMDEBUG}
 {$endif SYSTEMDEBUG}
+{$ifndef CPUAVR}
   while exitProc<>nil Do
   while exitProc<>nil Do
    Begin
    Begin
      InOutRes:=0;
      InOutRes:=0;
@@ -981,6 +987,7 @@ Begin
      exitProc:=nil;
      exitProc:=nil;
      current_exit();
      current_exit();
    End;
    End;
+{$endif CPUAVR}
 
 
 {$ifdef FPC_HAS_FEATURE_CONSOLEIO}
 {$ifdef FPC_HAS_FEATURE_CONSOLEIO}
   { the embedded system unit itself contains no routines for console i/o
   { the embedded system unit itself contains no routines for console i/o