From 66ebbbc5c2174eef82b6ebb0784fde8dd8bd1e40 Mon Sep 17 00:00:00 2001 From: Jonas Maebe Date: Tue, 20 Dec 2005 19:58:27 +0000 Subject: [PATCH] * always generate code which can be used to build dynamically loadable libraries with git-svn-id: trunk@2013 - --- compiler/ncgld.pas | 29 +++--------- compiler/ncgutil.pas | 4 +- compiler/powerpc/cgcpu.pas | 40 +++++++++++++++- compiler/powerpc/nppcld.pas | 91 +++++++++++-------------------------- 4 files changed, 72 insertions(+), 92 deletions(-) diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index 8e6ce01269..4ae6115a03 100644 --- a/compiler/ncgld.pas +++ b/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); @@ -236,24 +229,14 @@ 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; + location:=tglobalvarsym(symtableentry).localloc; {$ifdef segment_threadvars} - if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then - location.reference.segment:=NR_GS; + if (vo_is_thread_var in tabstractvarsym(symtableentry).varoptions) then + location.reference.segment:=NR_GS; {$endif} - end; end; else internalerror(200305102); diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index b36e3f5cb1..043b0d9c62 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -1970,9 +1970,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) {$ifndef segment_threadvars} and + if not(vo_is_dll_var in varoptions) {$ifndef segment_threadvars} and not(vo_is_thread_var in varoptions) {$endif} then reference_reset_symbol(localloc.reference,objectlibrary.newasmsymbol(mangledname,AB_EXTERNAL,AT_DATA),0); end; diff --git a/compiler/powerpc/cgcpu.pas b/compiler/powerpc/cgcpu.pas index f1bcba07ea..c6a2e52a7a 100644 --- a/compiler/powerpc/cgcpu.pas +++ b/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: *) @@ -1802,7 +1805,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 @@ -2111,12 +2114,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); + asmlist[al_picdata].concat(tai_symbol.create(l,0)); + asmlist[al_picdata].concat(tai_const.create_indirect_sym(objectlibrary.newasmsymbol(symname,AB_EXTERNAL,AT_DATA))); + asmlist[al_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; diff --git a/compiler/powerpc/nppcld.pas b/compiler/powerpc/nppcld.pas index a847b6fc7f..bf61980ad1 100644 --- a/compiler/powerpc/nppcld.pas +++ b/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); - asmlist[al_picdata].concat(tai_symbol.create(l,0)); - asmlist[al_picdata].concat(tai_const.create_indirect_sym(objectlibrary.newasmsymbol(tprocsym(symtableentry).procdef[1].mangledname,AB_EXTERNAL,AT_DATA))); - asmlist[al_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); - asmlist[al_picdata].concat(tai_symbol.create(l,0)); - asmlist[al_picdata].concat(tai_const.create_indirect_sym(objectlibrary.newasmsymbol(tglobalvarsym(symtableentry).mangledname,AB_EXTERNAL,AT_DATA))); - asmlist[al_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;