mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-06-03 13:18:35 +02:00
* factored out the code for loading a procvar address, and fixed all used
defs git-svn-id: branches/hlcgllvm@28475 -
This commit is contained in:
parent
63a3ff3c7f
commit
904a033ba2
@ -28,7 +28,7 @@ interface
|
|||||||
uses
|
uses
|
||||||
cpubase,
|
cpubase,
|
||||||
globtype,
|
globtype,
|
||||||
parabase,cgutils,
|
parabase,cgbase,cgutils,
|
||||||
symdef,node,ncal;
|
symdef,node,ncal;
|
||||||
|
|
||||||
type
|
type
|
||||||
@ -101,6 +101,12 @@ interface
|
|||||||
location, and create the paralocs array that will be passed to
|
location, and create the paralocs array that will be passed to
|
||||||
hlcg.a_call_* }
|
hlcg.a_call_* }
|
||||||
procedure pushparas;virtual;
|
procedure pushparas;virtual;
|
||||||
|
|
||||||
|
{ loads the code pointer of a complex procvar (one with a self/
|
||||||
|
parentfp/... and a procedure address) into a register and returns it }
|
||||||
|
function load_complex_procvar_codeptr: tregister; virtual;
|
||||||
|
{ loads the procvar code pointer into a register }
|
||||||
|
function load_procvar_codeptr: tregister;
|
||||||
public
|
public
|
||||||
procedure pass_generate_code;override;
|
procedure pass_generate_code;override;
|
||||||
destructor destroy;override;
|
destructor destroy;override;
|
||||||
@ -114,7 +120,7 @@ implementation
|
|||||||
cutils,verbose,globals,
|
cutils,verbose,globals,
|
||||||
cpuinfo,
|
cpuinfo,
|
||||||
symconst,symtable,symtype,symsym,defutil,paramgr,
|
symconst,symtable,symtype,symsym,defutil,paramgr,
|
||||||
cgbase,pass_2,
|
pass_2,
|
||||||
aasmbase,aasmtai,aasmdata,
|
aasmbase,aasmtai,aasmdata,
|
||||||
nbas,nmem,nld,ncnv,nutils,
|
nbas,nmem,nld,ncnv,nutils,
|
||||||
ncgutil,
|
ncgutil,
|
||||||
@ -758,6 +764,48 @@ implementation
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tcgcallnode.load_complex_procvar_codeptr: tregister;
|
||||||
|
var
|
||||||
|
srcreg: tregister;
|
||||||
|
codeprocdef: tabstractprocdef;
|
||||||
|
begin
|
||||||
|
{ this is safe even on i8086, because procvardef code pointers are
|
||||||
|
always far there (so the current state of far calls vs the state
|
||||||
|
of far calls where the procvardef was defined does not matter,
|
||||||
|
even though the procvardef constructor called by getcopyas looks at
|
||||||
|
it) }
|
||||||
|
codeprocdef:=tabstractprocdef(procdefinition.getcopyas(procvardef,pc_address_only));
|
||||||
|
result:=hlcg.getaddressregister(current_asmdata.CurrAsmList,codeprocdef);
|
||||||
|
{ in case we have a method pointer on a big endian target in registers,
|
||||||
|
the method address is stored in registerhi (it's the first field
|
||||||
|
in the tmethod record) }
|
||||||
|
if (right.location.loc in [LOC_REGISTER,LOC_CREGISTER]) then
|
||||||
|
begin
|
||||||
|
if not(right.location.size in [OS_PAIR,OS_SPAIR]) then
|
||||||
|
internalerror(2014081401);
|
||||||
|
if (target_info.endian=endian_big) then
|
||||||
|
srcreg:=right.location.registerhi
|
||||||
|
else
|
||||||
|
srcreg:=right.location.register;
|
||||||
|
hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,codeprocdef,codeprocdef,srcreg,result)
|
||||||
|
end
|
||||||
|
else
|
||||||
|
hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,codeprocdef,codeprocdef,right.location,result);
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
function tcgcallnode.load_procvar_codeptr: tregister;
|
||||||
|
begin
|
||||||
|
if not(procdefinition.is_addressonly) then
|
||||||
|
result:=load_complex_procvar_codeptr
|
||||||
|
else
|
||||||
|
begin
|
||||||
|
result:=hlcg.getaddressregister(current_asmdata.CurrAsmList,procdefinition);
|
||||||
|
hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,procdefinition,procdefinition,right.location,result);
|
||||||
|
end;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
procedure tcgcallnode.freeparas;
|
procedure tcgcallnode.freeparas;
|
||||||
var
|
var
|
||||||
ppn : tcgcallparanode;
|
ppn : tcgcallparanode;
|
||||||
@ -1012,29 +1060,19 @@ implementation
|
|||||||
{ now procedure variable case }
|
{ now procedure variable case }
|
||||||
begin
|
begin
|
||||||
secondpass(right);
|
secondpass(right);
|
||||||
callref:=false;
|
|
||||||
|
|
||||||
pvreg:=cg.getintregister(current_asmdata.CurrAsmList,proc_addr_size);
|
{ can we directly call the procvar in a memory location? }
|
||||||
{ Only load OS_ADDR from the reference (when converting to hlcg:
|
callref:=false;
|
||||||
watch out with procedure of object) }
|
|
||||||
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
if right.location.loc in [LOC_REFERENCE,LOC_CREFERENCE] then
|
||||||
begin
|
begin
|
||||||
href:=right.location.reference;
|
href:=right.location.reference;
|
||||||
callref:=can_call_ref(href);
|
callref:=can_call_ref(href);
|
||||||
if not callref then
|
end;
|
||||||
cg.a_load_ref_reg(current_asmdata.CurrAsmList,proc_addr_size,proc_addr_size,right.location.reference,pvreg)
|
|
||||||
end
|
if not callref then
|
||||||
else if right.location.loc in [LOC_REGISTER,LOC_CREGISTER] then
|
pvreg:=load_procvar_codeptr
|
||||||
begin
|
|
||||||
{ in case left is a method pointer and we are on a big endian target, then
|
|
||||||
the method address is stored in registerhi }
|
|
||||||
if (target_info.endian=endian_big) and (right.location.size in [OS_PAIR,OS_SPAIR]) then
|
|
||||||
hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,proc_addr_voidptrdef,proc_addr_voidptrdef,right.location.registerhi,pvreg)
|
|
||||||
else
|
|
||||||
hlcg.a_load_reg_reg(current_asmdata.CurrAsmList,proc_addr_voidptrdef,proc_addr_voidptrdef,right.location.register,pvreg);
|
|
||||||
end
|
|
||||||
else
|
else
|
||||||
hlcg.a_load_loc_reg(current_asmdata.CurrAsmList,proc_addr_voidptrdef,proc_addr_voidptrdef,right.location,pvreg);
|
pvreg:=NR_INVALID;
|
||||||
location_freetemp(current_asmdata.CurrAsmList,right.location);
|
location_freetemp(current_asmdata.CurrAsmList,right.location);
|
||||||
|
|
||||||
{ Load parameters that are in temporary registers in the
|
{ Load parameters that are in temporary registers in the
|
||||||
@ -1067,7 +1105,7 @@ implementation
|
|||||||
if callref then
|
if callref then
|
||||||
retloc:=do_call_ref(href)
|
retloc:=do_call_ref(href)
|
||||||
else
|
else
|
||||||
retloc:=hlcg.a_call_reg(current_asmdata.CurrAsmList,tabstractprocdef(procdefinition),pvreg,paralocs);
|
retloc:=hlcg.a_call_reg(current_asmdata.CurrAsmList,procdefinition,pvreg,paralocs);
|
||||||
extra_post_call_code;
|
extra_post_call_code;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user