Przeglądaj źródła

Merged revisions 2009,2013 via svnmerge from
svn+ssh://[email protected]/FPC/svn/fpc/trunk

r2009 (jonas)
* generate the procsymbol before generating the code for the procedure,
so that refences to this symbol are not treated as external


r2013 (jonas)
* always generate code which can be used to build dynamically loadable
libraries with

git-svn-id: branches/fixes_2_0@2019 -

Jonas Maebe 20 lat temu
rodzic
commit
658f8dfc95

+ 4 - 21
compiler/ncgld.pas

@@ -126,14 +126,7 @@ implementation
                begin
                   symtabletype:=symtable.symtabletype;
                   hregister:=NR_NO;
-                  if (target_info.system=system_powerpc_darwin) and
-                     ([vo_is_dll_var,vo_is_external] * tabstractvarsym(symtableentry).varoptions <> []) then
-                    begin
-                      if not(pi_needs_got in current_procinfo.flags) then
-                        internalerror(200403022);
-                      generate_picvaraccess;
-                    end
-                  else if (vo_is_dll_var in tabstractvarsym(symtableentry).varoptions) then
+                  if (vo_is_dll_var in tabstractvarsym(symtableentry).varoptions) then
                   { DLL variable }
                     begin
                       hregister:=cg.getaddressregister(exprasmlist);
@@ -234,20 +227,10 @@ implementation
                               globalsymtable,
                               staticsymtable :
                                 begin
-                                  if (target_info.system=system_powerpc_darwin) and
-                                    (cs_create_pic in aktmoduleswitches) then
-                                    begin
-                                      generate_picvaraccess;
-                                      if not(pi_needs_got in current_procinfo.flags) then
-                                        internalerror(200403023);
-                                    end
+                                  if tabstractnormalvarsym(symtableentry).localloc.loc=LOC_INVALID then
+                                    reference_reset_symbol(location.reference,objectlibrary.newasmsymbol(tglobalvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA),0)
                                   else
-                                    begin
-                                      if tabstractnormalvarsym(symtableentry).localloc.loc=LOC_INVALID then
-                                        reference_reset_symbol(location.reference,objectlibrary.newasmsymbol(tglobalvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA),0)
-                                      else
-                                        location:=tglobalvarsym(symtableentry).localloc;
-                                    end;
+                                    location:=tglobalvarsym(symtableentry).localloc;
                                 end;
                               else
                                 internalerror(200305102);

+ 1 - 3
compiler/ncgutil.pas

@@ -2039,9 +2039,7 @@ implementation
                               staticsymtable :
                                 begin
                                   { PIC, DLL and Threadvar need extra code and are handled in ncgld }
-                                  if not((target_info.system=system_powerpc_darwin) and
-                                    (cs_create_pic in aktmoduleswitches)) and
-                                     not(vo_is_dll_var in varoptions) and
+                                  if not(vo_is_dll_var in varoptions) and
                                      not(vo_is_thread_var in varoptions) then
                                     reference_reset_symbol(localloc.reference,objectlibrary.newasmsymbol(mangledname,AB_EXTERNAL,AT_DATA),0);
                                 end;

+ 39 - 1
compiler/powerpc/cgcpu.pas

@@ -97,6 +97,9 @@ unit cgcpu;
         procedure a_jmp_cond(list : taasmoutput;cond : TOpCmp;l: tasmlabel);
 
         procedure g_intf_wrapper(list: TAAsmoutput; procdef: tprocdef; const labelname: string; ioffset: longint);override;
+
+        function g_darwin_indirect_sym_load(list: taasmoutput; const symname: string): tregister;
+
       private
 
         (* NOT IN USE: *)
@@ -1808,7 +1811,7 @@ const
            { occurs, so now only ref.offset has to be loaded                         }
            else
              a_load_const_reg(list,OS_32,ref2.offset,r)
-         else if ref.index <> NR_NO Then
+         else if ref2.index <> NR_NO Then
            list.concat(taicpu.op_reg_reg_reg(A_ADD,r,ref2.base,ref2.index))
          else if (ref2.base <> NR_NO) and
                  (r <> ref2.base) then
@@ -2117,12 +2120,47 @@ const
       end;
 
 
+     function tcgppc.g_darwin_indirect_sym_load(list: taasmoutput; const symname: string): tregister;
+        var
+          l: tasmsymbol;
+          ref: treference;
+        begin
+          l:=objectlibrary.getasmsymbol('L'+symname+'$non_lazy_ptr');
+          if not(assigned(l)) then
+            begin
+              l:=objectlibrary.newasmsymbol('L'+symname+'$non_lazy_ptr',AB_COMMON,AT_DATA);
+              picdata.concat(tai_symbol.create(l,0));
+              picdata.concat(tai_const.create_indirect_sym(objectlibrary.newasmsymbol(symname,AB_EXTERNAL,AT_DATA)));
+              picdata.concat(tai_const.create_32bit(0));
+            end;
+          reference_reset_symbol(ref,l,0);
+{         ref.base:=current_procinfo.got;
+          ref.relsymbol:=current_procinfo.gotlabel;}
+          result := cg.getaddressregister(exprasmlist);
+          cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,result);
+        end;
+
     function tcgppc.fixref(list: taasmoutput; var ref: treference): boolean;
 
        var
          tmpreg: tregister;
        begin
          result := false;
+
+         if (target_info.system = system_powerpc_darwin) and
+            assigned(ref.symbol) and
+            (ref.symbol.defbind = AB_EXTERNAL) then
+           begin
+             tmpreg := g_darwin_indirect_sym_load(list,ref.symbol.name);
+             if (ref.base = NR_NO) then
+               ref.base := tmpreg
+             else if (ref.index = NR_NO) then
+               ref.index := tmpreg
+             else
+               list.concat(taicpu.op_reg_reg_reg(A_ADD,ref.base,ref.base,tmpreg));
+             ref.symbol := nil;
+           end;
+
          if (ref.base = NR_NO) then
            begin
              ref.base := ref.index;

+ 26 - 65
compiler/powerpc/nppcld.pas

@@ -31,7 +31,6 @@ unit nppcld;
     type
       tppcloadnode = class(tcgloadnode)
         procedure pass_2; override;
-        procedure generate_picvaraccess;override;
       end;
 
 
@@ -40,10 +39,9 @@ unit nppcld;
     uses
       verbose,
       systems,
-      globtype,globals,
-      cpubase,
-      cgutils,cgobj,
-      aasmbase,aasmtai,
+      globtype,globals,defutil,
+      cpubase, aasmbase, aasmtai,
+      cgutils,cgbase,cgobj,cgcpu,
       symconst,symsym,
       procinfo,
       nld;
@@ -53,73 +51,36 @@ unit nppcld;
       var
         l : tasmsymbol;
         ref : treference;
+        symname: string;
       begin
+        symname := '';
         case target_info.system of
           system_powerpc_darwin:
             begin
-              if (symtableentry.typ = procsym) and
-                 (tprocsym(symtableentry).owner.symtabletype in [staticsymtable,globalsymtable]) and
-                 (
-                  (not tprocsym(symtableentry).owner.iscurrentunit) or
-                  (po_external in tprocsym(symtableentry).procdef[1].procoptions)
-                 ) then
-                begin
-                  l:=objectlibrary.getasmsymbol('L'+tprocsym(symtableentry).procdef[1].mangledname+'$non_lazy_ptr');
-                  if not(assigned(l)) then
-                    begin
-                      l:=objectlibrary.newasmsymbol('L'+tprocsym(symtableentry).procdef[1].mangledname+'$non_lazy_ptr',AB_COMMON,AT_DATA);
-                      picdata.concat(tai_symbol.create(l,0));
-                      picdata.concat(tai_const.create_indirect_sym(objectlibrary.newasmsymbol(tprocsym(symtableentry).procdef[1].mangledname,AB_EXTERNAL,AT_DATA)));
-                      picdata.concat(tai_const.create_32bit(0));
-                    end;
-                  reference_reset_symbol(ref,l,0);
-                  reference_reset_base(location.reference,cg.getaddressregister(exprasmlist),0);
-                  cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,ref,location.reference.base);
-                end
-              else
-                inherited pass_2;
+              case symtableentry.typ of
+                procsym:
+                  begin
+                    if (po_external in tprocsym(symtableentry).procdef[1].procoptions) then
+                      symname := tprocsym(symtableentry).procdef[1].mangledname;
+                  end;
+                globalvarsym:
+                  begin
+                    if ([vo_is_dll_var,vo_is_external] * tglobalvarsym(symtableentry).varoptions <> []) then
+                      symname := tglobalvarsym(symtableentry).mangledname;
+                  end;
+              end;
             end;
-          else
-            inherited pass_2;
         end;
+        if (symname = '') then
+          inherited pass_2
+        else
+          begin
+            location_reset(location,LOC_REFERENCE,def_cgsize(resulttype.def));
+            reference_reset_base(location.reference,cg.getaddressregister(exprasmlist),0);
+            location.reference.base := tcgppc(cg).g_darwin_indirect_sym_load(exprasmlist,symname);
+          end;
       end;
-
-    procedure tppcloadnode.generate_picvaraccess;
-      var
-        l : tasmsymbol;
-        ref : treference;
-      begin
-        case target_info.system of
-          system_powerpc_darwin:
-            begin
-              if ([vo_is_dll_var,vo_is_external] * tglobalvarsym(symtableentry).varoptions <> []) or
-                 ((tglobalvarsym(symtableentry).owner.symtabletype in [staticsymtable,globalsymtable]) and
-                  (not(tglobalvarsym(symtableentry).owner.iscurrentunit) or
-                   (cs_create_pic in aktmoduleswitches))) then
-                begin
-                  l:=objectlibrary.getasmsymbol('L'+tglobalvarsym(symtableentry).mangledname+'$non_lazy_ptr');
-                  if not(assigned(l)) then
-                    begin
-                      l:=objectlibrary.newasmsymbol('L'+tglobalvarsym(symtableentry).mangledname+'$non_lazy_ptr',AB_COMMON,AT_DATA);
-                      picdata.concat(tai_symbol.create(l,0));
-                      picdata.concat(tai_const.create_indirect_sym(objectlibrary.newasmsymbol(tglobalvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA)));
-                      picdata.concat(tai_const.create_32bit(0));
-                    end;
-
-                  reference_reset_symbol(ref,l,0);
-{                  ref.base:=current_procinfo.got;
-                  ref.relsymbol:=current_procinfo.gotlabel;}
-                  reference_reset_base(location.reference,cg.getaddressregister(exprasmlist),0);
-                  cg.a_load_ref_reg(exprasmlist,OS_ADDR,OS_ADDR,ref,location.reference.base);
-                end
-              else
-                internalerror(200403021);
-            end
-          else
-            internalerror(200402291);
-        end;
-      end;
-
+      
 
 begin
    cloadnode:=tppcloadnode;

+ 10 - 4
compiler/psub.pas

@@ -608,7 +608,7 @@ implementation
         oldprocinfo : tprocinfo;
         oldaktmaxfpuregisters : longint;
         oldfilepos : tfileposinfo;
-        templist : Taasmoutput;
+        templist, symlist : Taasmoutput;
         headertai : tai;
       begin
         { the initialization procedure can be empty, then we
@@ -636,6 +636,7 @@ implementation
         aktbreaklabel:=nil;
         aktcontinuelabel:=nil;
         templist:=Taasmoutput.create;
+        symlist:=Taasmoutput.create;
 
         { add parast/localst to symtablestack }
         add_to_symtablestack;
@@ -681,6 +682,12 @@ implementation
             set_first_temp_offset;
             generate_parameter_info;
 
+            { allocate the symbol associated with the procedure, so that }
+            { references to itself are not treated as references to      }
+            { externals                                                  }
+            aktfilepos:=entrypos;
+            gen_proc_symbol(symlist);
+          
             { Allocate space in temp/registers for parast and localst }
             aktfilepos:=entrypos;
             gen_alloc_symtable(aktproccode,procdef.parast);
@@ -770,10 +777,9 @@ implementation
 
             { generate symbol and save end of header position }
             aktfilepos:=entrypos;
-            gen_proc_symbol(templist);
-            headertai:=tai(templist.last);
+            headertai:=tai(symlist.last);
             { insert symbol }
-            aktproccode.insertlist(templist);
+            aktproccode.insertlist(symlist);
 
             { Free space in temp/registers for parast and localst, must be
               done after gen_entry_code }