* migrated g_copyshortstring, g_incrrefcount and g_array_rtti_helper to thlcg

git-svn-id: trunk@21699 -
This commit is contained in:
Jonas Maebe 2012-06-24 21:36:28 +00:00
parent 60aedb19d6
commit 7c21cba1e2
7 changed files with 131 additions and 181 deletions

View File

@ -390,18 +390,6 @@ unit cgobj;
}
procedure g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : tcgint);virtual;
{# This should emit the opcode to a shortrstring from the source
to destination.
@param(source Source reference of copy)
@param(dest Destination reference of copy)
}
procedure g_copyshortstring(list : TAsmList;const source,dest : treference;len:byte);
procedure g_incrrefcount(list : TAsmList;t: tdef; const ref: treference);
procedure g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation;
const name: string);
{# Generates overflow checking code for a node }
procedure g_overflowcheck(list: TAsmList; const Loc:tlocation; def:tdef); virtual;abstract;
@ -2063,132 +2051,6 @@ implementation
end;
procedure tcg.g_copyshortstring(list : TAsmList;const source,dest : treference;len:byte);
var
cgpara1,cgpara2,cgpara3 : TCGPara;
begin
cgpara1.init;
cgpara2.init;
cgpara3.init;
paramanager.getintparaloc(pocall_default,1,voidpointertype,cgpara1);
paramanager.getintparaloc(pocall_default,2,voidpointertype,cgpara2);
paramanager.getintparaloc(pocall_default,3,s32inttype,cgpara3);
a_loadaddr_ref_cgpara(list,dest,cgpara3);
a_loadaddr_ref_cgpara(list,source,cgpara2);
a_load_const_cgpara(list,OS_S32,len,cgpara1);
paramanager.freecgpara(list,cgpara3);
paramanager.freecgpara(list,cgpara2);
paramanager.freecgpara(list,cgpara1);
allocallcpuregisters(list);
a_call_name(list,'FPC_SHORTSTR_ASSIGN',false);
deallocallcpuregisters(list);
cgpara3.done;
cgpara2.done;
cgpara1.done;
end;
procedure tcg.g_incrrefcount(list : TAsmList;t: tdef; const ref: treference);
var
href : treference;
incrfunc : string;
cgpara1,cgpara2 : TCGPara;
begin
cgpara1.init;
cgpara2.init;
paramanager.getintparaloc(pocall_default,1,voidpointertype,cgpara1);
paramanager.getintparaloc(pocall_default,2,voidpointertype,cgpara2);
if is_interfacecom_or_dispinterface(t) then
incrfunc:='FPC_INTF_INCR_REF'
else if is_ansistring(t) then
incrfunc:='FPC_ANSISTR_INCR_REF'
else if is_widestring(t) then
incrfunc:='FPC_WIDESTR_INCR_REF'
else if is_unicodestring(t) then
incrfunc:='FPC_UNICODESTR_INCR_REF'
else if is_dynamic_array(t) then
incrfunc:='FPC_DYNARRAY_INCR_REF'
else
incrfunc:='';
{ call the special incr function or the generic addref }
if incrfunc<>'' then
begin
{ widestrings aren't ref. counted on all platforms so we need the address
to create a real copy }
if is_widestring(t) then
a_loadaddr_ref_cgpara(list,ref,cgpara1)
else
{ these functions get the pointer by value }
a_load_ref_cgpara(list,OS_ADDR,ref,cgpara1);
paramanager.freecgpara(list,cgpara1);
allocallcpuregisters(list);
a_call_name(list,incrfunc,false);
deallocallcpuregisters(list);
end
else
begin
if is_open_array(t) then
InternalError(201103054);
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
a_loadaddr_ref_cgpara(list,href,cgpara2);
a_loadaddr_ref_cgpara(list,ref,cgpara1);
paramanager.freecgpara(list,cgpara1);
paramanager.freecgpara(list,cgpara2);
allocallcpuregisters(list);
a_call_name(list,'FPC_ADDREF',false);
deallocallcpuregisters(list);
end;
cgpara2.done;
cgpara1.done;
end;
procedure tcg.g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation; const name: string);
var
cgpara1,cgpara2,cgpara3: TCGPara;
href: TReference;
hreg, lenreg: TRegister;
begin
cgpara1.init;
cgpara2.init;
cgpara3.init;
paramanager.getintparaloc(pocall_default,1,voidpointertype,cgpara1);
paramanager.getintparaloc(pocall_default,2,voidpointertype,cgpara2);
paramanager.getintparaloc(pocall_default,3,ptrsinttype,cgpara3);
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
if highloc.loc=LOC_CONSTANT then
a_load_const_cgpara(list,OS_INT,highloc.value+1,cgpara3)
else
begin
if highloc.loc in [LOC_REGISTER,LOC_CREGISTER] then
hreg:=highloc.register
else
begin
hreg:=getintregister(list,OS_SINT);
a_load_loc_reg(list,OS_SINT,highloc,hreg);
end;
{ increment, converts high(x) to length(x) }
lenreg:=getintregister(list,OS_SINT);
a_op_const_reg_reg(list,OP_ADD,OS_SINT,1,hreg,lenreg);
a_load_reg_cgpara(list,OS_SINT,lenreg,cgpara3);
end;
a_loadaddr_ref_cgpara(list,href,cgpara2);
a_loadaddr_ref_cgpara(list,ref,cgpara1);
paramanager.freecgpara(list,cgpara1);
paramanager.freecgpara(list,cgpara2);
paramanager.freecgpara(list,cgpara3);
allocallcpuregisters(list);
a_call_name(list,name,false);
deallocallcpuregisters(list);
cgpara3.done;
cgpara2.done;
cgpara1.done;
end;
procedure tcg.g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);
begin
g_overflowCheck(list,loc,def);

View File

@ -278,18 +278,6 @@ unit hlcg2ll;
}
procedure g_concatcopy_unaligned(list : TAsmList;size: tdef; const source,dest : treference);override;
{# This should emit the opcode to a shortrstring from the source
to destination.
@param(source Source reference of copy)
@param(dest Destination reference of copy)
}
procedure g_copyshortstring(list : TAsmList;const source,dest : treference;strdef:tstringdef);override;
procedure g_incrrefcount(list : TAsmList;t: tdef; const ref: treference);override;
procedure g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation;
const name: string);override;
{# Generates overflow checking code for a node }
procedure g_overflowcheck(list: TAsmList; const Loc:tlocation; def:tdef); override;
@ -940,21 +928,6 @@ implementation
cg.g_concatcopy_unaligned(list,source,dest,size.size);
end;
procedure thlcg2ll.g_copyshortstring(list: TAsmList; const source, dest: treference; strdef: tstringdef);
begin
cg.g_copyshortstring(list,source,dest,strdef.len);
end;
procedure thlcg2ll.g_incrrefcount(list: TAsmList; t: tdef; const ref: treference);
begin
cg.g_incrrefcount(list,t,ref);
end;
procedure thlcg2ll.g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation; const name: string);
begin
cg.g_array_rtti_helper(list, t, ref, highloc, name);
end;
procedure thlcg2ll.g_overflowcheck(list: TAsmList; const Loc: tlocation; def: tdef);
begin
cg.g_overflowcheck(list,loc,def);

View File

@ -395,14 +395,14 @@ unit hlcgobj;
@param(dest Destination reference of copy)
}
procedure g_copyshortstring(list : TAsmList;const source,dest : treference;strdef:tstringdef);virtual;abstract;
procedure g_copyshortstring(list : TAsmList;const source,dest : treference;strdef:tstringdef);virtual;
procedure g_copyvariant(list : TAsmList;const source,dest : treference;vardef:tvariantdef);virtual;
procedure g_incrrefcount(list : TAsmList;t: tdef; const ref: treference);virtual;abstract;
procedure g_incrrefcount(list : TAsmList;t: tdef; const ref: treference);virtual;
procedure g_initialize(list : TAsmList;t : tdef;const ref : treference);virtual;
procedure g_finalize(list : TAsmList;t : tdef;const ref : treference);virtual;
procedure g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation;
const name: string);virtual;abstract;
const name: string);virtual;
{# Generates range checking code. It is to note
that this routine does not need to be overridden,
@ -2774,6 +2774,28 @@ implementation
g_concatcopy(list,size,source,dest);
end;
procedure thlcgobj.g_copyshortstring(list: TAsmList; const source, dest: treference; strdef: tstringdef);
var
cgpara1,cgpara2,cgpara3 : TCGPara;
begin
cgpara1.init;
cgpara2.init;
cgpara3.init;
paramanager.getintparaloc(pocall_default,1,voidpointertype,cgpara1);
paramanager.getintparaloc(pocall_default,2,voidpointertype,cgpara2);
paramanager.getintparaloc(pocall_default,3,s32inttype,cgpara3);
a_loadaddr_ref_cgpara(list,strdef,dest,cgpara3);
a_loadaddr_ref_cgpara(list,strdef,source,cgpara2);
a_load_const_cgpara(list,s32inttype,strdef.len,cgpara1);
paramanager.freecgpara(list,cgpara3);
paramanager.freecgpara(list,cgpara2);
paramanager.freecgpara(list,cgpara1);
g_call_system_proc(list,'fpc_shortstr_assign');
cgpara3.done;
cgpara2.done;
cgpara1.done;
end;
procedure thlcgobj.g_copyvariant(list: TAsmList; const source, dest: treference; vardef: tvariantdef);
var
cgpara1,cgpara2 : TCGPara;
@ -2793,6 +2815,56 @@ implementation
cgpara1.done;
end;
procedure thlcgobj.g_incrrefcount(list: TAsmList; t: tdef; const ref: treference);
var
href : treference;
incrfunc : string;
cgpara1,cgpara2 : TCGPara;
begin
cgpara1.init;
cgpara2.init;
paramanager.getintparaloc(pocall_default,1,voidpointertype,cgpara1);
paramanager.getintparaloc(pocall_default,2,voidpointertype,cgpara2);
if is_interfacecom_or_dispinterface(t) then
incrfunc:='fpc_intf_incr_ref'
else if is_ansistring(t) then
incrfunc:='fpc_ansistr_incr_ref'
else if is_widestring(t) then
incrfunc:='fpc_widestr_incr_ref'
else if is_unicodestring(t) then
incrfunc:='fpc_unicodestr_incr_ref'
else if is_dynamic_array(t) then
incrfunc:='fpc_dynarray_incr_ref'
else
incrfunc:='';
{ call the special incr function or the generic addref }
if incrfunc<>'' then
begin
{ widestrings aren't ref. counted on all platforms so we need the address
to create a real copy }
if is_widestring(t) then
a_loadaddr_ref_cgpara(list,t,ref,cgpara1)
else
{ these functions get the pointer by value }
a_load_ref_cgpara(list,t,ref,cgpara1);
paramanager.freecgpara(list,cgpara1);
g_call_system_proc(list,incrfunc);
end
else
begin
if is_open_array(t) then
InternalError(201103054);
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
paramanager.freecgpara(list,cgpara1);
paramanager.freecgpara(list,cgpara2);
g_call_system_proc(list,'fpc_addref');
end;
cgpara2.done;
cgpara1.done;
end;
procedure thlcgobj.g_initialize(list: TAsmList; t: tdef; const ref: treference);
var
href : treference;
@ -2888,6 +2960,49 @@ implementation
cgpara1.done;
end;
procedure thlcgobj.g_array_rtti_helper(list: TAsmList; t: tdef; const ref: treference; const highloc: tlocation; const name: string);
var
cgpara1,cgpara2,cgpara3: TCGPara;
href: TReference;
hreg, lenreg: TRegister;
begin
cgpara1.init;
cgpara2.init;
cgpara3.init;
paramanager.getintparaloc(pocall_default,1,voidpointertype,cgpara1);
paramanager.getintparaloc(pocall_default,2,voidpointertype,cgpara2);
paramanager.getintparaloc(pocall_default,3,ptrsinttype,cgpara3);
reference_reset_symbol(href,RTTIWriter.get_rtti_label(t,initrtti),0,sizeof(pint));
if highloc.loc=LOC_CONSTANT then
a_load_const_cgpara(list,ptrsinttype,highloc.value+1,cgpara3)
else
begin
if highloc.loc in [LOC_REGISTER,LOC_CREGISTER] then
hreg:=highloc.register
else
begin
hreg:=getintregister(list,ptrsinttype);
a_load_loc_reg(list,ptrsinttype,ptrsinttype,highloc,hreg);
end;
{ increment, converts high(x) to length(x) }
lenreg:=getintregister(list,ptrsinttype);
a_op_const_reg_reg(list,OP_ADD,ptrsinttype,1,hreg,lenreg);
a_load_reg_cgpara(list,ptrsinttype,lenreg,cgpara3);
end;
a_loadaddr_ref_cgpara(list,voidpointertype,href,cgpara2);
a_loadaddr_ref_cgpara(list,t,ref,cgpara1);
paramanager.freecgpara(list,cgpara1);
paramanager.freecgpara(list,cgpara2);
paramanager.freecgpara(list,cgpara3);
g_call_system_proc(list,name);
cgpara3.done;
cgpara2.done;
cgpara1.done;
end;
procedure thlcgobj.g_rangecheck(list: TAsmList; const l: tlocation; fromdef, todef: tdef);
var
{$if defined(cpu64bitalu) or defined(cpu32bitalu)}
@ -3764,7 +3879,7 @@ implementation
else
highloc.loc:=LOC_INVALID;
eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
g_array_rtti_helper(list,eldef,href,highloc,'FPC_FINALIZE_ARRAY');
g_array_rtti_helper(list,eldef,href,highloc,'fpc_finalize_array');
end
else
g_finalize(list,tparavarsym(p).vardef,href);
@ -3827,7 +3942,7 @@ implementation
{ open arrays do not contain correct element count in their rtti,
the actual count must be passed separately. }
eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
g_array_rtti_helper(list,eldef,href,highloc,'FPC_ADDREF_ARRAY');
g_array_rtti_helper(list,eldef,href,highloc,'fpc_addref_array');
end
else
g_incrrefcount(list,tparavarsym(p).vardef,href);
@ -3855,7 +3970,7 @@ implementation
else
highloc.loc:=LOC_INVALID;
eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
g_array_rtti_helper(list,eldef,href,highloc,'FPC_INITIALIZE_ARRAY');
g_array_rtti_helper(list,eldef,href,highloc,'fpc_initialize_array');
end
else
g_initialize(list,tparavarsym(p).vardef,href);

View File

@ -1527,7 +1527,7 @@ implementation
eleref: treference;
begin
{ only in case of initialisation, we have to set all elements to "empty" }
if name<>'FPC_INITIALIZE_ARRAY' then
if name<>'fpc_initialize_array' then
exit;
{ put array on the stack }
a_load_ref_stack(list,java_jlobject,ref,prepare_stack_for_ref(list,ref,false));
@ -1583,7 +1583,7 @@ implementation
not is_dynamic_array(t) then
begin
dummyloc.loc:=LOC_INVALID;
g_array_rtti_helper(list,tarraydef(t).elementdef,ref,dummyloc,'FPC_INITIALIZE_ARRAY')
g_array_rtti_helper(list,tarraydef(t).elementdef,ref,dummyloc,'fpc_initialize_array')
end
else if is_record(t) then
begin

View File

@ -203,8 +203,8 @@ implementation
if third=nil then
InternalError(201103063);
secondpass(third);
cg.g_array_rtti_helper(current_asmdata.CurrAsmList,tarraydef(resultdef).elementdef,
href,third.location,'FPC_FINALIZE_ARRAY');
hlcg.g_array_rtti_helper(current_asmdata.CurrAsmList,tarraydef(resultdef).elementdef,
href,third.location,'fpc_finalize_array');
end;
end
else

View File

@ -43,7 +43,7 @@ uses
aasmbase,aasmtai,aasmdata,
ncnv, ncon, pass_2,
cgbase, cpubase,
tgobj, cgobj, cgutils,ncgutil;
tgobj, cgobj, hlcgobj, cgutils,ncgutil;
{*****************************************************************************
@ -91,7 +91,7 @@ begin
(tg.sizeoftemp(current_asmdata.CurrAsmList,left.location.reference) = 256)) then
begin
tg.gethltemp(current_asmdata.CurrAsmList,cshortstringtype,256,tt_normal,href);
cg.g_copyshortstring(current_asmdata.CurrAsmList,left.location.reference,href,255);
hlcg.g_copyshortstring(current_asmdata.CurrAsmList,left.location.reference,href,tstringdef(cshortstringtype));
location_freetemp(current_asmdata.CurrAsmList,left.location);
{ return temp reference }
location_reset_ref(left.location,LOC_REFERENCE,def_cgsize(resultdef),1);

View File

@ -681,7 +681,7 @@ implementation
so we're allowed to include pi_do_call here; after pass1 is run, this isn't allowed anymore
}
include(current_procinfo.flags,pi_do_call);
cg.g_copyshortstring(list,href,localcopyloc.reference,tstringdef(tparavarsym(p).vardef).len)
hlcg.g_copyshortstring(list,href,localcopyloc.reference,tstringdef(tparavarsym(p).vardef));
end
else if tparavarsym(p).vardef.typ = variantdef then
begin
@ -739,10 +739,10 @@ implementation
eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
if not assigned(hsym) then
internalerror(201003031);
cg.g_array_rtti_helper(list,eldef,href,hsym.initialloc,'FPC_ADDREF_ARRAY');
hlcg.g_array_rtti_helper(list,eldef,href,hsym.initialloc,'fpc_addref_array');
end
else
cg.g_incrrefcount(list,tparavarsym(p).vardef,href);
hlcg.g_incrrefcount(list,tparavarsym(p).vardef,href);
end;
end;
vs_out :
@ -757,7 +757,7 @@ implementation
eldef:=tarraydef(tparavarsym(p).vardef).elementdef;
if not assigned(hsym) then
internalerror(201103033);
cg.g_array_rtti_helper(list,eldef,href,hsym.initialloc,'FPC_INITIALIZE_ARRAY');
hlcg.g_array_rtti_helper(list,eldef,href,hsym.initialloc,'fpc_initialize_array');
end
else
hlcg.g_initialize(list,tparavarsym(p).vardef,href);