diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index 64fcfb7b4e..e5b39ae3eb 100644 --- a/compiler/ncgld.pas +++ b/compiler/ncgld.pas @@ -38,6 +38,7 @@ interface procedure generate_nested_access(vs: tsym);virtual; procedure generate_absaddr_access(vs: tabsolutevarsym); virtual; procedure generate_threadvar_access(gvs: tstaticvarsym); virtual; + function use_indirect_symbol(gvs: tstaticvarsym): boolean; public procedure pass_generate_code;override; procedure changereflocation(const ref: treference); @@ -68,7 +69,7 @@ implementation uses cutils, systems, - verbose,globals,constexp, + verbose,globals,constexp,fmodule, nutils, symtable,symconst,symdef,defutil,paramgr,ncon,nbas,ncgrtti, aasmbase, @@ -273,9 +274,9 @@ implementation 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) + reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA,use_indirect_symbol(gvs)),0,location.reference.alignment) else - reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,location.reference.alignment) + reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,location.reference.alignment) else location:=gvs.localloc; end @@ -305,9 +306,9 @@ implementation hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,pvd,OC_EQ,0,hregister,norelocatelab); { no, call it with the index of the threadvar as parameter } if not(vo_is_weak_external in gvs.varoptions) then - reference_reset_symbol(tvref,current_asmdata.RefAsmSymbol(gvs.mangledname),0,sizeof(pint)) + reference_reset_symbol(tvref,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA,use_indirect_symbol(gvs)),0,sizeof(pint)) else - reference_reset_symbol(tvref,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,sizeof(pint)); + reference_reset_symbol(tvref,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,sizeof(pint)); href:=tvref; hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList, tv_rec, @@ -347,6 +348,26 @@ implementation end; + function tcgloadnode.use_indirect_symbol(gvs:tstaticvarsym):boolean; + begin + { we are using a direct reference if any of the following is true: + - the target does not support packages + - the target does not use indirect references + - the variable is declared as (weak) external + - G- is set + - the variable is located inside the same unit } + result:=(tf_supports_packages in target_info.flags) and + (target_info.system in systems_indirect_var_imports) and + (gvs.varoptions*[vo_is_external,vo_is_weak_external]=[]) and + (gvs.owner.symtabletype in [globalsymtable,staticsymtable]) and + (cs_imported_data in current_settings.localswitches) and + not sym_is_owned_by(gvs,current_module.globalsymtable) and + ( + (current_module.globalsymtable=current_module.localsymtable) or + not sym_is_owned_by(gvs,current_module.localsymtable) + ); + end; + procedure tcgloadnode.pass_generate_code; var hregister : tregister; @@ -414,10 +435,12 @@ 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 + if not(vo_is_weak_external in gvs.varoptions) then + reference_reset_symbol(location.reference,current_asmdata.RefAsmSymbol(gvs.mangledname,AT_DATA,use_indirect_symbol(gvs)),0,location.reference.alignment) + else + reference_reset_symbol(location.reference,current_asmdata.WeakRefAsmSymbol(gvs.mangledname,AT_DATA),0,location.reference.alignment) + end else location:=gvs.localloc; end;