Browse Source

Generate indirect symbols for global variables and load them indirectly when necessary.

ptconst.pas, read_typed_const:
  * generate an indirect symbol for the const data using the indirect_suffix constant
ngenutil.pas, tnodeutils.insertbssdata:
  * generate an indirect symbol for the uninitialized data using the indirect_suffix constant
ncgld.pas, tcgloadnode.pass_generate_code:
  * load static variables indirectly if the following conditions are true:
      - the target supports packages (otherwise this is a waste of cycles)
      - the variable is not external
      - IMPORTEDDATA is active
      - the variable is loaded from a different unit

git-svn-id: branches/svenbarth/packages@28642 -
svenbarth 11 years ago
parent
commit
a7008cc17c
3 changed files with 49 additions and 5 deletions
  1. 31 5
      compiler/ncgld.pas
  2. 9 0
      compiler/ngenutil.pas
  3. 9 0
      compiler/ptconst.pas

+ 31 - 5
compiler/ncgld.pas

@@ -67,7 +67,7 @@ implementation
     uses
       cutils,
       systems,
-      verbose,globals,constexp,
+      verbose,globals,constexp,fmodule,
       nutils,
       symtable,symconst,symdef,defutil,paramgr,ncon,nbas,ncgrtti,
       aasmbase,
@@ -415,10 +415,36 @@ implementation
                 else
                   begin
                     if gvs.localloc.loc=LOC_INVALID then
-                      if not(vo_is_weak_external in gvs.varoptions) then
-                        reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname),0,location.reference.alignment)
-                      else
-                        reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,location.reference.alignment)
+                      begin
+                        { we are using a direct reference if:
+                          - the target does not support packages
+                          - the variable is declared as (weak) external
+                          - G- is set
+                          - the variable is located inside the same unit }
+                        if not (tf_supports_packages in target_info.flags) or
+                            (vo_is_external in gvs.varoptions) or (vo_is_weak_external in gvs.varoptions) or
+                            not (cs_imported_data in current_settings.localswitches) or
+                            sym_is_owned_by(gvs,current_module.globalsymtable) or
+                            (
+                              (current_module.globalsymtable<>current_module.localsymtable) and
+                              sym_is_owned_by(gvs,current_module.localsymtable)
+                            ) then
+                          begin
+                            { direct reference }
+                            if not(vo_is_weak_external in gvs.varoptions) then
+                              reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname),0,location.reference.alignment)
+                            else
+                              reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,location.reference.alignment)
+                          end
+                        else
+                          begin
+                            { indirect reference }
+                            hregister:=cg.getaddressregister(current_asmdata.CurrAsmList);
+                            location.reference.symbol:=current_asmdata.RefAsmSymbol(gvs.mangledname+indirect_suffix);
+                            cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_ADDR,OS_ADDR,location.reference,hregister);
+                            reference_reset_base(location.reference,hregister,0,location.reference.alignment);
+                          end;
+                      end
                     else
                       location:=gvs.localloc;
                   end;

+ 9 - 0
compiler/ngenutil.pas

@@ -571,6 +571,15 @@ implementation
         end
       else
         list.concat(Tai_datablock.create(sym.mangledname,l));
+
+      { add indirect symbol }
+      if (vo_has_section in sym.varoptions) or (sectype<>sec_rodata) then
+        new_section(list,sec_rodata,lower(sym.mangledname),const_align(sym.vardef.alignment));
+      labind:=current_asmdata.DefineAsmSymbol(sym.mangledname+indirect_suffix,AB_GLOBAL,AT_DATA);
+      list.concat(Tai_symbol.Create_Global(labind,0));
+      list.concat(Tai_const.Createname(sym.mangledname,AT_DATA,0));
+      list.concat(tai_symbol_end.Create(labind));
+
       current_filepos:=storefilepos;
     end;
 

+ 9 - 0
compiler/ptconst.pas

@@ -50,6 +50,7 @@ implementation
         reslist      : tasmlist;
         restree,
         previnit     : tnode;
+        labind       : tasmsymbol;
       begin
         { mark the staticvarsym as typedconst }
         include(sym.varoptions,vo_is_typed_const);
@@ -158,6 +159,14 @@ implementation
             list.concatlist(reslist);
             reslist.free;
             list.concat(tai_symbol_end.Createname(sym.mangledname));
+
+            { add indirect symbol }
+            if (vo_has_section in sym.varoptions) or (cursectype<>sec_rodata) then
+              new_section(list,sec_rodata,lower(sym.mangledname+indirect_suffix),const_align(sym.vardef.alignment));
+            labind:=current_asmdata.DefineAsmSymbol(sym.mangledname+indirect_suffix,AB_GLOBAL,AT_DATA);
+            list.concat(Tai_symbol.Create_Global(labind,0));
+            list.concat(Tai_const.Createname(sym.mangledname,AT_DATA,0));
+            list.concat(tai_symbol_end.Create(labind));
           end
         else
           begin