mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-01 15:42:31 +02:00
* renamed thlcgobj.g_set_addr_nonbitpacked_record_field_ref() to
thlcgobj.g_set_addr_nonbitpacked_field_ref() and adjusted it so that it also works for objects/classes (if the incoming reference points to the start of the class contents) o factored out the related code from tllvmsubscriptnode git-svn-id: trunk@32411 -
This commit is contained in:
parent
c8a5994e2e
commit
eaeb9d8351
@ -539,9 +539,9 @@ unit hlcgobj;
|
||||
reference if necessary }
|
||||
procedure g_ptrtypecast_ref(list: TAsmList; fromdef, todef: tpointerdef; var ref: treference); virtual;
|
||||
|
||||
{ update a reference pointing to the start address of a record so it
|
||||
refers to the indicated field }
|
||||
procedure g_set_addr_nonbitpacked_record_field_ref(list: TAsmList; recdef: trecorddef; field: tfieldvarsym; var recref: treference); virtual;
|
||||
{ update a reference pointing to the start address of a record/object/
|
||||
class (contents) so it refers to the indicated field }
|
||||
procedure g_set_addr_nonbitpacked_field_ref(list: TAsmList; recdef: tabstractrecorddef; field: tfieldvarsym; var recref: treference); virtual;
|
||||
{ load a register/constant into a record field by name }
|
||||
protected
|
||||
procedure g_setup_load_field_by_name(list: TAsmList; recdef: trecorddef; const name: TIDString; const recref: treference; out fref: treference; out fielddef: tdef);
|
||||
@ -3844,7 +3844,7 @@ implementation
|
||||
{ nothing to do }
|
||||
end;
|
||||
|
||||
procedure thlcgobj.g_set_addr_nonbitpacked_record_field_ref(list: TAsmList; recdef: trecorddef; field: tfieldvarsym; var recref: treference);
|
||||
procedure thlcgobj.g_set_addr_nonbitpacked_field_ref(list: TAsmList; recdef: tabstractrecorddef; field: tfieldvarsym; var recref: treference);
|
||||
begin
|
||||
inc(recref.offset,field.fieldoffset);
|
||||
recref.alignment:=newalignment(recref.alignment,field.fieldoffset);
|
||||
@ -3863,7 +3863,7 @@ implementation
|
||||
field:=tfieldvarsym(sym);
|
||||
fref:=recref;
|
||||
fielddef:=field.vardef;
|
||||
g_set_addr_nonbitpacked_record_field_ref(list,recdef,field,fref);
|
||||
g_set_addr_nonbitpacked_field_ref(list,recdef,field,fref);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -97,7 +97,7 @@ uses
|
||||
procedure g_ptrtypecast_reg(list: TAsmList; fromdef, todef: tpointerdef; reg: tregister); override;
|
||||
procedure g_ptrtypecast_ref(list: TAsmList; fromdef, todef: tpointerdef; var ref: treference); override;
|
||||
|
||||
procedure g_set_addr_nonbitpacked_record_field_ref(list: TAsmList; recdef: trecorddef; field: tfieldvarsym; var recref: treference); override;
|
||||
procedure g_set_addr_nonbitpacked_field_ref(list: TAsmList; recdef: tabstractrecorddef; field: tfieldvarsym; var recref: treference); override;
|
||||
|
||||
procedure a_loadmm_ref_reg(list: TAsmList; fromsize, tosize: tdef; const ref: treference; reg: tregister; shuffle: pmmshuffle); override;
|
||||
procedure a_loadmm_reg_ref(list: TAsmList; fromsize, tosize: tdef; reg: tregister; const ref: treference; shuffle: pmmshuffle); override;
|
||||
@ -1224,22 +1224,54 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure thlcgllvm.g_set_addr_nonbitpacked_record_field_ref(list: TAsmList; recdef: trecorddef; field: tfieldvarsym; var recref: treference);
|
||||
procedure thlcgllvm.g_set_addr_nonbitpacked_field_ref(list: TAsmList; recdef: tabstractrecorddef; field: tfieldvarsym; var recref: treference);
|
||||
var
|
||||
llvmfielddef,
|
||||
llvmfieldptrdef,
|
||||
subscriptdef: tdef;
|
||||
parentdef,
|
||||
subscriptdef,
|
||||
currentstructdef,
|
||||
llvmfielddef: tdef;
|
||||
newbase: tregister;
|
||||
implicitpointer: boolean;
|
||||
begin
|
||||
implicitpointer:=is_implicit_pointer_object_type(recdef);
|
||||
currentstructdef:=recdef;
|
||||
{ in case the field is part of a parent of the current object,
|
||||
index into the parents until we're at the parent containing the
|
||||
field; if it's an implicit pointer type, these embedded parents
|
||||
will be of the structure type of the class rather than of the
|
||||
class time itself -> one indirection fewer }
|
||||
while field.owner<>tabstractrecorddef(currentstructdef).symtable do
|
||||
begin
|
||||
{ only objectdefs have parents and hence the owner of the
|
||||
fieldvarsym can be different from the current def's owner }
|
||||
parentdef:=tobjectdef(currentstructdef).childof;
|
||||
if implicitpointer then
|
||||
newbase:=getaddressregister(list,parentdef)
|
||||
else
|
||||
newbase:=getaddressregister(list,cpointerdef.getreusable(parentdef));
|
||||
recref:=make_simple_ref(list,recref,recdef);
|
||||
if implicitpointer then
|
||||
subscriptdef:=currentstructdef
|
||||
else
|
||||
subscriptdef:=cpointerdef.getreusable(currentstructdef);
|
||||
{ recurse into the first field }
|
||||
list.concat(taillvm.getelementptr_reg_size_ref_size_const(newbase,subscriptdef,recref,s32inttype,0,true));
|
||||
reference_reset_base(recref,subscriptdef,newbase,field.offsetfromllvmfield,newalignment(recref.alignment,field.fieldoffset));
|
||||
{ go to the parent }
|
||||
currentstructdef:=parentdef;
|
||||
end;
|
||||
{ get the type of the corresponding field in the llvm shadow
|
||||
definition }
|
||||
llvmfielddef:=tabstractrecordsymtable(recdef.symtable).llvmst[field].def;
|
||||
subscriptdef:=cpointerdef.getreusable(recdef);
|
||||
llvmfielddef:=tabstractrecordsymtable(tabstractrecorddef(currentstructdef).symtable).llvmst[field].def;
|
||||
if implicitpointer then
|
||||
subscriptdef:=currentstructdef
|
||||
else
|
||||
subscriptdef:=cpointerdef.getreusable(currentstructdef);
|
||||
{ load the address of that shadow field }
|
||||
newbase:=hlcg.getaddressregister(list,cpointerdef.getreusable(llvmfielddef));
|
||||
recref:=thlcgllvm(hlcg).make_simple_ref(list,recref,recdef);
|
||||
newbase:=getaddressregister(list,cpointerdef.getreusable(llvmfielddef));
|
||||
recref:=make_simple_ref(list,recref,recdef);
|
||||
list.concat(taillvm.getelementptr_reg_size_ref_size_const(newbase,subscriptdef,recref,s32inttype,field.llvmfieldnr,true));
|
||||
reference_reset_base(recref,cpointerdef.getreusable(field.vardef),newbase,field.offsetfromllvmfield,newalignment(recref.alignment,field.fieldoffset+field.offsetfromllvmfield));
|
||||
reference_reset_base(recref,subscriptdef,newbase,field.offsetfromllvmfield,newalignment(recref.alignment,field.fieldoffset+field.offsetfromllvmfield));
|
||||
{ in case of an 80 bits extended type, typecast from an array of 10
|
||||
bytes (used because otherwise llvm will allocate the ABI-defined
|
||||
size for extended, which is usually larger) into an extended }
|
||||
@ -1250,7 +1282,7 @@ implementation
|
||||
adjust the type of the pointer }
|
||||
if (field.offsetfromllvmfield<>0) or
|
||||
(llvmfielddef<>field.vardef) then
|
||||
hlcg.g_ptrtypecast_ref(list,cpointerdef.getreusable(llvmfielddef),cpointerdef.getreusable(field.vardef),recref);
|
||||
g_ptrtypecast_ref(list,cpointerdef.getreusable(llvmfielddef),cpointerdef.getreusable(field.vardef),recref);
|
||||
end;
|
||||
|
||||
|
||||
|
@ -65,12 +65,7 @@ implementation
|
||||
|
||||
function tllvmsubscriptnode.handle_platform_subscript: boolean;
|
||||
var
|
||||
parentdef,
|
||||
subscriptdef,
|
||||
currentstructdef,
|
||||
llvmfielddef: tdef;
|
||||
newbase: tregister;
|
||||
implicitpointer: boolean;
|
||||
begin
|
||||
if not(location.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then
|
||||
internalerror(2014011905);
|
||||
@ -85,56 +80,7 @@ implementation
|
||||
end
|
||||
else
|
||||
begin
|
||||
implicitpointer:=is_implicit_pointer_object_type(left.resultdef);
|
||||
currentstructdef:=left.resultdef;
|
||||
{ in case the field is part of a parent of the current object,
|
||||
index into the parents until we're at the parent containing the
|
||||
field; if it's an implicit pointer type, these embedded parents
|
||||
will be of the structure type of the class rather than of the
|
||||
class time itself -> one indirection fewer }
|
||||
while vs.owner<>tabstractrecorddef(currentstructdef).symtable do
|
||||
begin
|
||||
{ only objectdefs have parents and hence the owner of the
|
||||
fieldvarsym can be different from the current def's owner }
|
||||
parentdef:=tobjectdef(currentstructdef).childof;
|
||||
if implicitpointer then
|
||||
newbase:=hlcg.getaddressregister(current_asmdata.CurrAsmList,parentdef)
|
||||
else
|
||||
newbase:=hlcg.getaddressregister(current_asmdata.CurrAsmList,cpointerdef.getreusable(parentdef));
|
||||
location.reference:=thlcgllvm(hlcg).make_simple_ref(current_asmdata.CurrAsmList,location.reference,left.resultdef);
|
||||
if implicitpointer then
|
||||
subscriptdef:=currentstructdef
|
||||
else
|
||||
subscriptdef:=cpointerdef.getreusable(currentstructdef);
|
||||
{ recurse into the first field }
|
||||
current_asmdata.CurrAsmList.concat(taillvm.getelementptr_reg_size_ref_size_const(newbase,subscriptdef,location.reference,s32inttype,0,true));
|
||||
reference_reset_base(location.reference,newbase,vs.offsetfromllvmfield,newalignment(location.reference.alignment,vs.fieldoffset));
|
||||
{ go to the parent }
|
||||
currentstructdef:=parentdef;
|
||||
end;
|
||||
{ get the type of the corresponding field in the llvm shadow
|
||||
definition }
|
||||
llvmfielddef:=tabstractrecordsymtable(tabstractrecorddef(currentstructdef).symtable).llvmst[vs].def;
|
||||
if implicitpointer then
|
||||
subscriptdef:=currentstructdef
|
||||
else
|
||||
subscriptdef:=cpointerdef.getreusable(currentstructdef);
|
||||
{ load the address of that shadow field }
|
||||
newbase:=hlcg.getaddressregister(current_asmdata.CurrAsmList,cpointerdef.getreusable(llvmfielddef));
|
||||
location.reference:=thlcgllvm(hlcg).make_simple_ref(current_asmdata.CurrAsmList,location.reference,left.resultdef);
|
||||
current_asmdata.CurrAsmList.concat(taillvm.getelementptr_reg_size_ref_size_const(newbase,subscriptdef,location.reference,s32inttype,vs.llvmfieldnr,true));
|
||||
reference_reset_base(location.reference,newbase,vs.offsetfromllvmfield,newalignment(location.reference.alignment,vs.fieldoffset+vs.offsetfromllvmfield));
|
||||
{ in case of an 80 bits extended type, typecast from an array of 10
|
||||
bytes (used because otherwise llvm will allocate the ABI-defined
|
||||
size for extended, which is usually larger) into an extended }
|
||||
if (llvmfielddef.typ=floatdef) and
|
||||
(tfloatdef(llvmfielddef).floattype=s80real) then
|
||||
hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(carraydef.getreusable(u8inttype,10)),cpointerdef.getreusable(s80floattype),location.reference);
|
||||
{ if it doesn't match the requested field exactly (variant record),
|
||||
adjust the type of the pointer }
|
||||
if (vs.offsetfromllvmfield<>0) or
|
||||
(llvmfielddef<>resultdef) then
|
||||
hlcg.g_ptrtypecast_ref(current_asmdata.CurrAsmList,cpointerdef.getreusable(llvmfielddef),cpointerdef.getreusable(resultdef),location.reference);
|
||||
hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,tabstractrecorddef(left.resultdef),vs,location.reference);
|
||||
location.size:=def_cgsize(resultdef);
|
||||
result:=true;
|
||||
end;
|
||||
|
@ -309,7 +309,7 @@ implementation
|
||||
else
|
||||
reference_reset_symbol(tvref,current_asmdata.WeakRefAsmSymbol(gvs.mangledname),0,sizeof(pint));
|
||||
href:=tvref;
|
||||
hlcg.g_set_addr_nonbitpacked_record_field_ref(current_asmdata.CurrAsmList,
|
||||
hlcg.g_set_addr_nonbitpacked_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);
|
||||
@ -334,7 +334,7 @@ implementation
|
||||
sizeof(pint) - Threadvar value in single threading }
|
||||
hlcg.a_label(current_asmdata.CurrAsmList,norelocatelab);
|
||||
href:=tvref;
|
||||
hlcg.g_set_addr_nonbitpacked_record_field_ref(current_asmdata.CurrAsmList,
|
||||
hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,
|
||||
tv_rec,
|
||||
tfieldvarsym(tv_non_mt_data_field),href);
|
||||
{ load in the same "hregister" as above, so after this sequence
|
||||
@ -381,7 +381,7 @@ implementation
|
||||
location_reset_ref(location,LOC_CREFERENCE,def_cgsize(cansistringtype),cansistringtype.size);
|
||||
location.reference.symbol:=current_asmdata.RefAsmSymbol(make_mangledname('RESSTR',symtableentry.owner,symtableentry.name),AT_DATA);
|
||||
vd:=search_system_type('TRESOURCESTRINGRECORD').typedef;
|
||||
hlcg.g_set_addr_nonbitpacked_record_field_ref(
|
||||
hlcg.g_set_addr_nonbitpacked_field_ref(
|
||||
current_asmdata.CurrAsmList,
|
||||
trecorddef(vd),
|
||||
tfieldvarsym(search_struct_member(trecorddef(vd),'CURRENTVALUE')),
|
||||
@ -1325,7 +1325,7 @@ implementation
|
||||
internalerror(2015102901);
|
||||
{ write changing field update href to the next element }
|
||||
fref:=href;
|
||||
hlcg.g_set_addr_nonbitpacked_record_field_ref(current_asmdata.CurrAsmList,trecorddef(eledef),varfield,fref);
|
||||
hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,trecorddef(eledef),varfield,fref);
|
||||
if vaddr then
|
||||
begin
|
||||
hlcg.location_force_mem(current_asmdata.CurrAsmList,hp.left.location,lt);
|
||||
@ -1337,7 +1337,7 @@ implementation
|
||||
hlcg.a_load_loc_ref(current_asmdata.CurrAsmList,hp.left.resultdef,varfield.vardef,hp.left.location,fref);
|
||||
{ update href to the vtype field and write it }
|
||||
fref:=href;
|
||||
hlcg.g_set_addr_nonbitpacked_record_field_ref(current_asmdata.CurrAsmList,trecorddef(eledef),varvtypefield,fref);
|
||||
hlcg.g_set_addr_nonbitpacked_field_ref(current_asmdata.CurrAsmList,trecorddef(eledef),varvtypefield,fref);
|
||||
hlcg.a_load_const_ref(current_asmdata.CurrAsmList,varvtypefield.vardef,vtype,fref);
|
||||
{ goto next array element }
|
||||
advancearrayoffset(href,elesize);
|
||||
|
Loading…
Reference in New Issue
Block a user