mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-09-21 20:09:51 +02:00
* converted threadvar loading to high level code generator and updated/added
comments git-svn-id: trunk@31644 -
This commit is contained in:
parent
83ae160057
commit
19882aea7e
@ -255,12 +255,19 @@ implementation
|
|||||||
|
|
||||||
procedure tcgloadnode.generate_threadvar_access(gvs: tstaticvarsym);
|
procedure tcgloadnode.generate_threadvar_access(gvs: tstaticvarsym);
|
||||||
var
|
var
|
||||||
|
respara,
|
||||||
paraloc1 : tcgpara;
|
paraloc1 : tcgpara;
|
||||||
|
fieldptrdef,
|
||||||
pvd : tdef;
|
pvd : tdef;
|
||||||
endrelocatelab,
|
endrelocatelab,
|
||||||
norelocatelab : tasmlabel;
|
norelocatelab : tasmlabel;
|
||||||
|
tvref,
|
||||||
href : treference;
|
href : treference;
|
||||||
hregister : tregister;
|
hregister : tregister;
|
||||||
|
tv_rec : trecorddef;
|
||||||
|
tv_index_field,
|
||||||
|
tv_non_mt_data_field: tsym;
|
||||||
|
tmpresloc: tlocation;
|
||||||
begin
|
begin
|
||||||
if (tf_section_threadvars in target_info.flags) then
|
if (tf_section_threadvars in target_info.flags) then
|
||||||
begin
|
begin
|
||||||
@ -279,51 +286,63 @@ implementation
|
|||||||
a relocate function is available. When the function
|
a relocate function is available. When the function
|
||||||
is available it is called to retrieve the address.
|
is available it is called to retrieve the address.
|
||||||
Otherwise the address is loaded with the symbol
|
Otherwise the address is loaded with the symbol
|
||||||
|
|
||||||
The code needs to be in the order to first handle the
|
|
||||||
call and then the address load to be sure that the
|
|
||||||
register that is used for returning is the same (PFV)
|
|
||||||
}
|
}
|
||||||
|
tv_rec:=get_threadvar_record(resultdef,tv_index_field,tv_non_mt_data_field);
|
||||||
|
fieldptrdef:=cpointerdef.getreusable(resultdef);
|
||||||
current_asmdata.getjumplabel(norelocatelab);
|
current_asmdata.getjumplabel(norelocatelab);
|
||||||
current_asmdata.getjumplabel(endrelocatelab);
|
current_asmdata.getjumplabel(endrelocatelab);
|
||||||
{ make sure hregister can't allocate the register necessary for the parameter }
|
{ make sure hregister can't allocate the register necessary for the parameter }
|
||||||
pvd:=search_system_type('TRELOCATETHREADVARHANDLER').typedef;
|
pvd:=search_system_type('TRELOCATETHREADVARHANDLER').typedef;
|
||||||
if pvd.typ<>procvardef then
|
if pvd.typ<>procvardef then
|
||||||
internalerror(2012120901);
|
internalerror(2012120901);
|
||||||
|
|
||||||
|
{ FPC_THREADVAR_RELOCATE is nil? }
|
||||||
paraloc1.init;
|
paraloc1.init;
|
||||||
paramanager.getintparaloc(current_asmdata.CurrAsmList,tprocvardef(pvd),1,paraloc1);
|
paramanager.getintparaloc(current_asmdata.CurrAsmList,tprocvardef(pvd),1,paraloc1);
|
||||||
hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,pvd);
|
hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,pvd);
|
||||||
reference_reset_symbol(href,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0,pvd.size);
|
reference_reset_symbol(href,current_asmdata.RefAsmSymbol('FPC_THREADVAR_RELOCATE'),0,pvd.size);
|
||||||
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,pvd,pvd,href,hregister);
|
hlcg.a_load_ref_reg(current_asmdata.CurrAsmList,pvd,pvd,href,hregister);
|
||||||
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,pvd,OC_EQ,0,hregister,norelocatelab);
|
hlcg.a_cmp_const_reg_label(current_asmdata.CurrAsmList,pvd,OC_EQ,0,hregister,norelocatelab);
|
||||||
{ don't save the allocated register else the result will be destroyed later }
|
{ no, call it with the index of the threadvar as parameter }
|
||||||
if not(vo_is_weak_external in gvs.varoptions) then
|
if not(vo_is_weak_external in gvs.varoptions) then
|
||||||
reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),0,sizeof(pint))
|
reference_reset_symbol(tvref,current_asmdata.RefAsmSymbol(gvs.mangledname),0,sizeof(pint))
|
||||||
else
|
else
|
||||||
reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,sizeof(pint));
|
reference_reset_symbol(tvref,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,sizeof(pint));
|
||||||
cg.a_load_ref_cgpara(current_asmdata.CurrAsmList,OS_32,href,paraloc1);
|
href:=tvref;
|
||||||
|
hlcg.g_set_addr_nonbitpacked_record_field_ref(current_asmdata.CurrAsmList,
|
||||||
|
tv_rec,
|
||||||
|
tfieldvarsym(tv_index_field),href);
|
||||||
|
hlcg.a_load_ref_cgpara(current_asmdata.CurrAsmList,tfieldvarsym(tv_index_field).vardef,href,paraloc1);
|
||||||
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
|
paramanager.freecgpara(current_asmdata.CurrAsmList,paraloc1);
|
||||||
paraloc1.done;
|
|
||||||
cg.allocallcpuregisters(current_asmdata.CurrAsmList);
|
cg.allocallcpuregisters(current_asmdata.CurrAsmList);
|
||||||
cg.a_call_reg(current_asmdata.CurrAsmList,hregister);
|
{ result is the address of the threadvar }
|
||||||
|
respara:=hlcg.a_call_reg(current_asmdata.CurrAsmList,tprocvardef(pvd),hregister,[@paraloc1]);
|
||||||
|
paraloc1.done;
|
||||||
cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
|
cg.deallocallcpuregisters(current_asmdata.CurrAsmList);
|
||||||
cg.getcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
|
|
||||||
cg.ungetcpuregister(current_asmdata.CurrAsmList,NR_FUNCTION_RESULT_REG);
|
{ load the address of the result in hregister }
|
||||||
hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,voidpointertype);
|
hregister:=hlcg.getaddressregister(current_asmdata.CurrAsmList,fieldptrdef);
|
||||||
cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_INT,OS_ADDR,NR_FUNCTION_RESULT_REG,hregister);
|
location_reset(tmpresloc,LOC_REGISTER,OS_ADDR);
|
||||||
cg.a_jmp_always(current_asmdata.CurrAsmList,endrelocatelab);
|
tmpresloc.register:=hregister;
|
||||||
cg.a_label(current_asmdata.CurrAsmList,norelocatelab);
|
hlcg.gen_load_cgpara_loc(current_asmdata.CurrAsmList,fieldptrdef,respara,tmpresloc,true);
|
||||||
|
respara.resetiftemp;
|
||||||
|
hlcg.a_jmp_always(current_asmdata.CurrAsmList,endrelocatelab);
|
||||||
|
|
||||||
{ no relocation needed, load the address of the variable only, the
|
{ no relocation needed, load the address of the variable only, the
|
||||||
layout of a threadvar is (4 bytes pointer):
|
layout of a threadvar is:
|
||||||
0 - Threadvar index
|
0 - Threadvar index
|
||||||
sizeof(pint) - Threadvar value in single threading }
|
sizeof(pint) - Threadvar value in single threading }
|
||||||
if not(vo_is_weak_external in gvs.varoptions) then
|
hlcg.a_label(current_asmdata.CurrAsmList,norelocatelab);
|
||||||
reference_reset_symbol(href,current_asmdata.RefAsmSymbol(gvs.mangledname),sizeof(pint),sizeof(pint))
|
href:=tvref;
|
||||||
else
|
hlcg.g_set_addr_nonbitpacked_record_field_ref(current_asmdata.CurrAsmList,
|
||||||
reference_reset_symbol(href,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),sizeof(pint),sizeof(pint));
|
tv_rec,
|
||||||
hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,resultdef,voidpointertype,href,hregister);
|
tfieldvarsym(tv_non_mt_data_field),href);
|
||||||
cg.a_label(current_asmdata.CurrAsmList,endrelocatelab);
|
{ load in the same "hregister" as above, so after this sequence
|
||||||
hlcg.reference_reset_base(location.reference,voidpointertype,hregister,0,location.reference.alignment);
|
the address of the threadvar is always in hregister }
|
||||||
|
hlcg.a_loadaddr_ref_reg(current_asmdata.CurrAsmList,resultdef,fieldptrdef,href,hregister);
|
||||||
|
hlcg.a_label(current_asmdata.CurrAsmList,endrelocatelab);
|
||||||
|
|
||||||
|
hlcg.reference_reset_base(location.reference,fieldptrdef,hregister,0,location.reference.alignment);
|
||||||
end;
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user