From adb6f59eefac9d657cea3f8285db5d2ed4f586ee Mon Sep 17 00:00:00 2001 From: peter Date: Sun, 24 Oct 2004 11:44:28 +0000 Subject: [PATCH] * small regvar fixes * loadref parameter removed from concatcopy,incrrefcount,etc --- compiler/cgobj.pas | 139 ++++++++++++---------------------------- compiler/htypechk.pas | 17 +++-- compiler/i386/cgcpu.pas | 31 ++++----- compiler/ncgcal.pas | 38 ++++++----- compiler/ncgflw.pas | 14 ++-- compiler/ncgld.pas | 50 +++++++++------ compiler/ncgopt.pas | 8 ++- compiler/ncgutil.pas | 105 ++++++++++++++++++------------ compiler/ncnv.pas | 23 ++++--- compiler/nld.pas | 16 ++++- compiler/pdecsub.pas | 9 ++- compiler/rautils.pas | 10 ++- compiler/x86/cgx86.pas | 17 +++-- 13 files changed, 247 insertions(+), 230 deletions(-) diff --git a/compiler/cgobj.pas b/compiler/cgobj.pas index d4396169d7..8cfe74f1ce 100644 --- a/compiler/cgobj.pas +++ b/compiler/cgobj.pas @@ -326,47 +326,38 @@ unit cgobj; procedure g_maybe_testself(list : taasmoutput;reg:tregister); procedure g_maybe_testvmt(list : taasmoutput;reg:tregister;objdef:tobjectdef); {# This should emit the opcode to copy len bytes from the source - to destination, if loadref is true, it assumes that it first must load - the source address from the memory location where - source points to. + to destination. It must be overriden for each new target processor. @param(source Source reference of copy) @param(dest Destination reference of copy) - @param(loadref Is the source reference a pointer to the actual source (TRUE), is it the actual source address (FALSE)) } - procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint;loadref : boolean);virtual; abstract; + procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint);virtual; abstract; {# This should emit the opcode to copy len bytes from the an unaligned source - to destination, if loadref is true, it assumes that it first must load - the source address from the memory location where - source points to. + to destination. It must be overriden for each new target processor. @param(source Source reference of copy) @param(dest Destination reference of copy) - @param(loadref Is the source reference a pointer to the actual source (TRUE), is it the actual source address (FALSE)) } - procedure g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint;loadref : boolean);virtual; + procedure g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint);virtual; {# This should emit the opcode to a shortrstring from the source - to destination, if loadref is true, it assumes that it first must load - the source address from the memory location where - source points to. + to destination. @param(source Source reference of copy) @param(dest Destination reference of copy) - @param(loadref Is the source reference a pointer to the actual source (TRUE), is it the actual source address (FALSE)) } - procedure g_copyshortstring(list : taasmoutput;const source,dest : treference;len:byte;loadref : boolean); + procedure g_copyshortstring(list : taasmoutput;const source,dest : treference;len:byte); - procedure g_incrrefcount(list : taasmoutput;t: tdef; const ref: treference;loadref : boolean); - procedure g_decrrefcount(list : taasmoutput;t: tdef; const ref: treference;loadref : boolean); - procedure g_initialize(list : taasmoutput;t : tdef;const ref : treference;loadref : boolean); - procedure g_finalize(list : taasmoutput;t : tdef;const ref : treference;loadref : boolean); + procedure g_incrrefcount(list : taasmoutput;t: tdef; const ref: treference); + procedure g_decrrefcount(list : taasmoutput;t: tdef; const ref: treference); + procedure g_initialize(list : taasmoutput;t : tdef;const ref : treference); + procedure g_finalize(list : taasmoutput;t : tdef;const ref : treference); {# Generates range checking code. It is to note that this routine does not need to be overriden, @@ -381,7 +372,7 @@ unit cgobj; procedure g_overflowcheck(list: taasmoutput; const Loc:tlocation; def:tdef); virtual;abstract; procedure g_overflowCheck_loc(List:TAasmOutput;const Loc:TLocation;def:TDef;ovloc : tlocation);virtual; - procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;const lenloc:tlocation;elesize:aint;loadref:boolean);virtual; + procedure g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;const lenloc:tlocation;elesize:aint;destreg:tregister);virtual; procedure g_releasevaluepara_openarray(list : taasmoutput;const ref:treference);virtual; {# Emits instructions when compilation is done in profile @@ -783,7 +774,7 @@ implementation ref.offset:=paraloc.location^.reference.offset; { use concatcopy, because it can also be a float which fails when load_ref_ref is used } - g_concatcopy(list,r,ref,tcgsize2size[size],false); + g_concatcopy(list,r,ref,tcgsize2size[size]); end else internalerror(2002071004); @@ -826,7 +817,7 @@ implementation if not(paraloc.location^.loc in [LOC_REFERENCE,LOC_CREFERENCE]) then internalerror(2003010901); reference_reset_base(ref,paraloc.location^.reference.index,paraloc.location^.reference.offset); - g_concatcopy(list,r,ref,size,false); + g_concatcopy(list,r,ref,size); end; @@ -1024,7 +1015,7 @@ implementation begin reference_reset_base(href,paraloc.location^.reference.index,paraloc.location^.reference.offset); { concatcopy should choose the best way to copy the data } - g_concatcopy(list,ref,href,tcgsize2size[size],false); + g_concatcopy(list,ref,href,tcgsize2size[size]); end else internalerror(200402201); @@ -1380,13 +1371,13 @@ implementation end; - procedure tcg.g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint;loadref : boolean); + procedure tcg.g_concatcopy_unaligned(list : taasmoutput;const source,dest : treference;len : aint); begin - g_concatcopy(list,source,dest,len,loadref); + g_concatcopy(list,source,dest,len); end; - procedure tcg.g_copyshortstring(list : taasmoutput;const source,dest : treference;len:byte;loadref : boolean); + procedure tcg.g_copyshortstring(list : taasmoutput;const source,dest : treference;len:byte); var paraloc1,paraloc2,paraloc3 : TCGPara; begin @@ -1399,10 +1390,7 @@ implementation paramanager.allocparaloc(list,paraloc3); a_paramaddr_ref(list,dest,paraloc3); paramanager.allocparaloc(list,paraloc2); - if loadref then - a_param_ref(list,OS_ADDR,source,paraloc2) - else - a_paramaddr_ref(list,source,paraloc2); + a_paramaddr_ref(list,source,paraloc2); paramanager.allocparaloc(list,paraloc1); a_param_const(list,OS_INT,len,paraloc1); paramanager.freeparaloc(list,paraloc3); @@ -1419,7 +1407,7 @@ implementation end; - procedure tcg.g_incrrefcount(list : taasmoutput;t: tdef; const ref: treference;loadref : boolean); + procedure tcg.g_incrrefcount(list : taasmoutput;t: tdef; const ref: treference); var href : treference; incrfunc : string; @@ -1457,8 +1445,8 @@ implementation { call the special incr function or the generic addref } if incrfunc<>'' then begin - { these functions get the pointer by value } paramanager.allocparaloc(list,paraloc1); + { these functions get the pointer by value } a_param_ref(list,OS_ADDR,ref,paraloc1); paramanager.freeparaloc(list,paraloc1); alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); @@ -1471,10 +1459,7 @@ implementation paramanager.allocparaloc(list,paraloc2); a_paramaddr_ref(list,href,paraloc2); paramanager.allocparaloc(list,paraloc1); - if loadref then - a_param_ref(list,OS_ADDR,ref,paraloc1) - else - a_paramaddr_ref(list,ref,paraloc1); + a_paramaddr_ref(list,ref,paraloc1); paramanager.freeparaloc(list,paraloc1); paramanager.freeparaloc(list,paraloc2); alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); @@ -1486,9 +1471,8 @@ implementation end; - procedure tcg.g_decrrefcount(list : taasmoutput;t: tdef; const ref: treference; loadref:boolean); + procedure tcg.g_decrrefcount(list : taasmoutput;t: tdef; const ref: treference); var - hreg : tregister; href : treference; decrfunc : string; needrtti : boolean; @@ -1535,10 +1519,7 @@ implementation a_paramaddr_ref(list,href,paraloc2); end; paramanager.allocparaloc(list,paraloc1); - if loadref then - a_param_ref(list,OS_ADDR,ref,paraloc1) - else - a_paramaddr_ref(list,ref,paraloc1); + a_paramaddr_ref(list,ref,paraloc1); paramanager.freeparaloc(list,paraloc1); if needrtti then paramanager.freeparaloc(list,paraloc2); @@ -1552,10 +1533,7 @@ implementation paramanager.allocparaloc(list,paraloc2); a_paramaddr_ref(list,href,paraloc2); paramanager.allocparaloc(list,paraloc1); - if loadref then - a_param_ref(list,OS_ADDR,ref,paraloc1) - else - a_paramaddr_ref(list,ref,paraloc1); + a_paramaddr_ref(list,ref,paraloc1); paramanager.freeparaloc(list,paraloc1); paramanager.freeparaloc(list,paraloc2); alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); @@ -1564,23 +1542,13 @@ implementation end; { Temp locations need always to be reset to 0 } if tg.istemp(ref) then - begin - if loadref then - begin - hreg:=getaddressregister(list); - a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,hreg); - reference_reset_base(href,hreg,0); - a_load_const_ref(list,OS_ADDR,0,href); - end - else - a_load_const_ref(list,OS_ADDR,0,ref); - end; + a_load_const_ref(list,OS_ADDR,0,ref); paraloc2.done; paraloc1.done; end; - procedure tcg.g_initialize(list : taasmoutput;t : tdef;const ref : treference;loadref : boolean); + procedure tcg.g_initialize(list : taasmoutput;t : tdef;const ref : treference); var href : treference; paraloc1,paraloc2 : TCGPara; @@ -1600,10 +1568,7 @@ implementation paramanager.allocparaloc(list,paraloc2); a_paramaddr_ref(list,href,paraloc2); paramanager.allocparaloc(list,paraloc1); - if loadref then - a_param_ref(list,OS_ADDR,ref,paraloc1) - else - a_paramaddr_ref(list,ref,paraloc1); + a_paramaddr_ref(list,ref,paraloc1); paramanager.freeparaloc(list,paraloc1); paramanager.freeparaloc(list,paraloc2); alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); @@ -1617,9 +1582,8 @@ implementation end; - procedure tcg.g_finalize(list : taasmoutput;t : tdef;const ref : treference;loadref : boolean); + procedure tcg.g_finalize(list : taasmoutput;t : tdef;const ref : treference); var - hreg : tregister; href : treference; paraloc1,paraloc2 : TCGPara; begin @@ -1631,20 +1595,10 @@ implementation is_widestring(t) or is_interfacecom(t) then begin - g_decrrefcount(list,t,ref,loadref); + g_decrrefcount(list,t,ref); { Temp locations are already reset to 0 } if not tg.istemp(ref) then - begin - if loadref then - begin - hreg:=getaddressregister(list); - a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,hreg); - reference_reset_base(href,hreg,0); - a_load_const_ref(list,OS_ADDR,0,href); - end - else - a_load_const_ref(list,OS_ADDR,0,ref); - end; + a_load_const_ref(list,OS_ADDR,0,ref); end else begin @@ -1652,10 +1606,7 @@ implementation paramanager.allocparaloc(list,paraloc2); a_paramaddr_ref(list,href,paraloc2); paramanager.allocparaloc(list,paraloc1); - if loadref then - a_param_ref(list,OS_ADDR,ref,paraloc1) - else - a_paramaddr_ref(list,ref,paraloc1); + a_paramaddr_ref(list,ref,paraloc1); paramanager.freeparaloc(list,paraloc1); paramanager.freeparaloc(list,paraloc2); alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); @@ -1885,9 +1836,9 @@ implementation Entry/Exit Code Functions *****************************************************************************} - procedure tcg.g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;const lenloc:tlocation;elesize:aint;loadref:boolean); + procedure tcg.g_copyvaluepara_openarray(list : taasmoutput;const ref:treference;const lenloc:tlocation;elesize:aint;destreg:tregister); var - sizereg,sourcereg,destreg : tregister; + sizereg,sourcereg : tregister; paraloc1,paraloc2,paraloc3 : TCGPara; begin { because ppc abi doesn't support dynamic stack allocation properly @@ -1895,22 +1846,14 @@ implementation } { allocate two registers for len and source } sizereg:=getintregister(list,OS_INT); - sourcereg:=getintregister(list,OS_ADDR); - destreg:=getintregister(list,OS_ADDR); + sourcereg:=getaddressregister(list); { calculate necessary memory } a_load_loc_reg(list,OS_INT,lenloc,sizereg); a_op_const_reg(list,OP_ADD,OS_INT,1,sizereg); a_op_const_reg(list,OP_IMUL,OS_INT,elesize,sizereg); { load source } - if loadref then - a_load_ref_reg(list,OS_ADDR,OS_ADDR,ref,sourcereg) - else - begin - if (ref.index<>NR_NO) or (ref.offset<>0) then - internalerror(200410126); - a_load_reg_reg(list,OS_ADDR,OS_ADDR,ref.base,sourcereg); - end; + a_loadaddr_ref_reg(list,ref,sourcereg); { do getmem call } paraloc1.init; @@ -1924,12 +1867,8 @@ implementation dealloccpuregisters(list,R_FPUREGISTER,paramanager.get_volatile_registers_fpu(pocall_default)); dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default)); paraloc1.done; + { return the new address } a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,destreg); - { patch the new address } - if loadref then - a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,ref) - else - a_load_reg_reg(list,OS_ADDR,OS_ADDR,NR_FUNCTION_RESULT_REG,ref.base); { do move call } paraloc1.init; @@ -2092,7 +2031,11 @@ finalization end. { $Log$ - Revision 1.179 2004-10-15 09:14:16 mazen + Revision 1.180 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.179 2004/10/15 09:14:16 mazen - remove $IFDEF DELPHI and related code - remove $IFDEF FPCPROCVAR and related code diff --git a/compiler/htypechk.pas b/compiler/htypechk.pas index c1affa46cd..5a713cf7a0 100644 --- a/compiler/htypechk.pas +++ b/compiler/htypechk.pas @@ -912,10 +912,13 @@ implementation (tobjectdef(fromdef).is_related(tobjectdef(todef))))) and (fromdef.size<>todef.size) then begin - { in TP it is allowed to typecast to smaller types } - if not(m_tp7 in aktmodeswitches) or - (todef.size>fromdef.size) then - CGMessagePos2(hp.fileinfo,type_e_typecast_wrong_size_for_assignment,tostr(fromdef.size),tostr(todef.size)); + { in TP it is allowed to typecast to smaller types. But the variable can't + be in a register } + if (m_tp7 in aktmodeswitches) or + (todef.sizeNR_NO) or (ref.offset<>0) then - internalerror(200410123); - a_load_reg_reg(list,OS_INT,OS_INT,ref.base,NR_ESI) - end; + a_loadaddr_ref_reg(list,ref,NR_ESI); { scheduled .... } list.concat(Taicpu.op_reg(A_INC,S_L,NR_ECX)); @@ -407,15 +400,9 @@ unit cgcpu; ungetcpuregister(list,NR_ECX); ungetcpuregister(list,NR_ESI); - { patch the new address } - if loadref then - a_load_reg_ref(list,OS_INT,OS_INT,NR_ESP,ref) - else - begin - { Don't use a_load_reg_reg, that will add a move instruction - that can confuse the reg allocator } - list.concat(Taicpu.Op_reg_reg(A_MOV,S_L,NR_ESP,ref.base)); - end; + { patch the new address, but don't use a_load_reg_reg, that will add a move instruction + that can confuse the reg allocator } + list.concat(Taicpu.Op_reg_reg(A_MOV,S_L,NR_ESP,destreg)); end; @@ -571,7 +558,11 @@ begin end. { $Log$ - Revision 1.57 2004-10-15 09:16:21 mazen + Revision 1.58 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.57 2004/10/15 09:16:21 mazen - remove $IFDEF DELPHI and related code - remove $IFDEF FPCPROCVAR and related code diff --git a/compiler/ncgcal.pas b/compiler/ncgcal.pas index 555f60636d..bc222078f7 100644 --- a/compiler/ncgcal.pas +++ b/compiler/ncgcal.pas @@ -197,7 +197,7 @@ implementation else begin reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset); - cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false); + cg.g_concatcopy(exprasmlist,left.location.reference,href,size); end; end; else @@ -311,7 +311,7 @@ implementation end else reference_reset_base(href,tempcgpara.location^.reference.index,tempcgpara.location^.reference.offset); - cg.g_concatcopy(exprasmlist,left.location.reference,href,size,false); + cg.g_concatcopy(exprasmlist,left.location.reference,href,size); {$else i386} cg.a_param_copy_ref(exprasmlist,left.resulttype.def.size,left.location.reference,tempcgpara); {$endif i386} @@ -536,17 +536,9 @@ implementation tempnode.pass_2; location := tempnode.location; tempnode.free; - cg.g_decrrefcount(exprasmlist,resulttype.def,location.reference,false); + cg.g_decrrefcount(exprasmlist,resulttype.def,location.reference); cg.a_load_reg_ref(exprasmlist,OS_ADDR,OS_ADDR,hregister,location.reference); end; - - { When the result is not used we need to finalize the result and - can release the temp } - if not(cnf_return_value_used in callnodeflags) then - begin - cg.g_finalize(exprasmlist,resulttype.def,location.reference,false); - tg.ungetiftemp(exprasmlist,location.reference) - end; end else { normal (ordinal,float,pointer) result value } @@ -637,6 +629,18 @@ implementation location_reset(location,LOC_VOID,OS_NO); end; end; + + { When the result is not used we need to finalize the result and + can release the temp } + if not(cnf_return_value_used in callnodeflags) then + begin + if location.loc=LOC_REFERENCE then + begin + if resulttype.def.needs_inittable then + cg.g_finalize(exprasmlist,resulttype.def,location.reference); + tg.ungetiftemp(exprasmlist,location.reference) + end; + end; end; @@ -806,7 +810,7 @@ implementation not assigned(funcretnode) then begin tg.gettemptyped(exprasmlist,resulttype.def,tt_normal,refcountedtemp); - cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false); + cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp); end; regs_to_save_int:=paramanager.get_volatile_registers_int(procdefinition.proccalloption); @@ -1066,7 +1070,7 @@ implementation not paramanager.ret_in_param(resulttype.def,procdefinition.proccalloption) then begin tg.gettemptyped(exprasmlist,resulttype.def,tt_normal,refcountedtemp); - cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp,false); + cg.g_decrrefcount(exprasmlist,resulttype.def,refcountedtemp); end; { Push parameters, still use the old current_procinfo. This @@ -1177,7 +1181,7 @@ implementation begin { data which must be finalized ? } if (resulttype.def.needs_inittable) then - cg.g_finalize(exprasmlist,resulttype.def,location.reference,false); + cg.g_finalize(exprasmlist,resulttype.def,location.reference); { release unused temp } tg.ungetiftemp(exprasmlist,location.reference) end @@ -1239,7 +1243,11 @@ begin end. { $Log$ - Revision 1.178 2004-10-15 09:14:16 mazen + Revision 1.179 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.178 2004/10/15 09:14:16 mazen - remove $IFDEF DELPHI and related code - remove $IFDEF FPCPROCVAR and related code diff --git a/compiler/ncgflw.pas b/compiler/ncgflw.pas index 7808de4ae4..a6c63f6c40 100644 --- a/compiler/ncgflw.pas +++ b/compiler/ncgflw.pas @@ -928,7 +928,7 @@ implementation objectlibrary.getlabel(lastonlabel); get_exception_temps(exprasmlist,excepttemps); - new_exception(exprasmlist,excepttemps,1,exceptlabel); + new_exception(exprasmlist,excepttemps,exceptlabel); { try block } { set control flow labels for the try block } @@ -988,7 +988,7 @@ implementation objectlibrary.getlabel(doobjectdestroyandreraise); get_exception_temps(exprasmlist,destroytemps); - new_exception(exprasmlist,destroytemps,1,doobjectdestroyandreraise); + new_exception(exprasmlist,destroytemps,doobjectdestroyandreraise); { here we don't have to reset flowcontrol } { the default and on flowcontrols are handled equal } @@ -1176,7 +1176,7 @@ implementation { call setjmp, and jump to finally label on non-zero result } get_exception_temps(exprasmlist,excepttemps); - new_exception(exprasmlist,excepttemps,1,doobjectdestroyandreraise); + new_exception(exprasmlist,excepttemps,doobjectdestroyandreraise); oldaktbreaklabel:=nil; oldaktcontinuelabel:=nil; @@ -1326,7 +1326,7 @@ implementation { call setjmp, and jump to finally label on non-zero result } get_exception_temps(exprasmlist,excepttemps); - new_exception(exprasmlist,excepttemps,1,finallylabel); + new_exception(exprasmlist,excepttemps,finallylabel); { try code } if assigned(left) then @@ -1443,7 +1443,11 @@ begin end. { $Log$ - Revision 1.100 2004-09-26 17:45:30 peter + Revision 1.101 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.100 2004/09/26 17:45:30 peter * simple regvar support, not yet finished Revision 1.99 2004/09/25 14:23:54 peter diff --git a/compiler/ncgld.pas b/compiler/ncgld.pas index e71fafe5e3..638b8d9183 100644 --- a/compiler/ncgld.pas +++ b/compiler/ncgld.pas @@ -419,7 +419,10 @@ implementation useless for string constants} if (right.resulttype.def.needs_inittable) and (right.nodetype<>stringconstn) then - cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference,false); + begin + location_get_data_ref(exprasmlist,right.location,href,false); + cg.g_incrrefcount(exprasmlist,right.resulttype.def,href); + end; if codegenerror then exit; @@ -433,7 +436,10 @@ implementation secondpass(left); { decrement destination reference counter } if (left.resulttype.def.needs_inittable) then - cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference,false); + begin + location_get_data_ref(exprasmlist,left.location,href,false); + cg.g_decrrefcount(exprasmlist,left.resulttype.def,href); + end; if codegenerror then exit; end; @@ -443,14 +449,17 @@ implementation { calculate left sides } { don't do it yet if it's a crgister (JM) } if not(nf_concat_string in flags) then - begin - secondpass(left); - { decrement destination reference counter } - if (left.resulttype.def.needs_inittable) then - cg.g_decrrefcount(exprasmlist,left.resulttype.def,left.location.reference,false); - if codegenerror then - exit; - end; + begin + secondpass(left); + { decrement destination reference counter } + if (left.resulttype.def.needs_inittable) then + begin + location_get_data_ref(exprasmlist,left.location,href,false); + cg.g_decrrefcount(exprasmlist,left.resulttype.def,href); + end; + if codegenerror then + exit; + end; { left can't be never a 64 bit LOC_REGISTER, so the 3. arg } { can be false } @@ -459,7 +468,10 @@ implementation useless for string constants} if (right.resulttype.def.needs_inittable) and (right.nodetype<>stringconstn) then - cg.g_incrrefcount(exprasmlist,right.resulttype.def,right.location.reference,false); + begin + location_get_data_ref(exprasmlist,right.location,href,false); + cg.g_incrrefcount(exprasmlist,right.resulttype.def,href); + end; if codegenerror then exit; @@ -576,11 +588,9 @@ implementation len:=left.resulttype.def.size; if (right.location.reference.offset mod sizeof(aint)<>0) and (len>sizeof(aint)) then - cg.g_concatcopy_unaligned(exprasmlist,right.location.reference, - left.location.reference,len,false) + cg.g_concatcopy_unaligned(exprasmlist,right.location.reference,left.location.reference,len) else - cg.g_concatcopy(exprasmlist,right.location.reference, - left.location.reference,len,false); + cg.g_concatcopy(exprasmlist,right.location.reference,left.location.reference,len); end; else internalerror(200203284); @@ -892,9 +902,9 @@ implementation begin if is_shortstring(hp.left.resulttype.def) then cg.g_copyshortstring(exprasmlist,hp.left.location.reference,href, - Tstringdef(hp.left.resulttype.def).len,false) + Tstringdef(hp.left.resulttype.def).len) else - cg.g_concatcopy(exprasmlist,hp.left.location.reference,href,elesize,false); + cg.g_concatcopy(exprasmlist,hp.left.location.reference,href,elesize); end; else begin @@ -923,7 +933,11 @@ begin end. { $Log$ - Revision 1.127 2004-10-10 20:21:18 peter + Revision 1.128 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.127 2004/10/10 20:21:18 peter * passing a var parameter to var parameter is now also allowed for register locations (=regvars) diff --git a/compiler/ncgopt.pas b/compiler/ncgopt.pas index 530577851d..7d3ab1b747 100644 --- a/compiler/ncgopt.pas +++ b/compiler/ncgopt.pas @@ -98,7 +98,7 @@ begin not(nf_use_strconcat in flags) then begin tg.Gettemp(exprasmlist,256,tt_normal,href); - cg.g_copyshortstring(exprasmlist,left.location.reference,href,255,false); + cg.g_copyshortstring(exprasmlist,left.location.reference,href,255); location_freetemp(exprasmlist,left.location); { return temp reference } location_reset(left.location,LOC_REFERENCE,def_cgsize(resulttype.def)); @@ -196,7 +196,11 @@ end. { $Log$ - Revision 1.15 2004-09-25 14:23:54 peter + Revision 1.16 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.15 2004/09/25 14:23:54 peter * ungetregister is now only used for cpuregisters, renamed to ungetcpuregister * renamed (get|unget)explicitregister(s) to ..cpuregister diff --git a/compiler/ncgutil.pas b/compiler/ncgutil.pas index dbb852f732..4c907a40fb 100644 --- a/compiler/ncgutil.pas +++ b/compiler/ncgutil.pas @@ -49,6 +49,10 @@ interface procedure location_force_mem(list:TAAsmoutput;var l:tlocation); procedure location_force_mmregscalar(list:TAAsmoutput;var l: tlocation;maybeconst:boolean); + { Retrieve the location of the data pointed to in location l, when the location is + a register it is expected to contain the address of the data } + procedure location_get_data_ref(list:TAAsmoutput;const l:tlocation;var ref:treference;loadref:boolean); + function maybe_pushfpu(list:taasmoutput;needed : byte;var l:tlocation) : boolean; procedure gen_proc_symbol(list:Taasmoutput); @@ -92,7 +96,7 @@ interface procedure get_exception_temps(list:taasmoutput;var t:texceptiontemps); procedure unget_exception_temps(list:taasmoutput;const t:texceptiontemps); - procedure new_exception(list:TAAsmoutput;const t:texceptiontemps;a:aint;exceptlabel:tasmlabel); + procedure new_exception(list:TAAsmoutput;const t:texceptiontemps;exceptlabel:tasmlabel); procedure free_exception(list:TAAsmoutput;const t:texceptiontemps;a:aint;endexceptlabel:tasmlabel;onlyfree:boolean); procedure insertconstdata(sym : ttypedconstsym); @@ -282,7 +286,7 @@ implementation end; - procedure new_exception(list:TAAsmoutput;const t:texceptiontemps;a:aint;exceptlabel:tasmlabel); + procedure new_exception(list:TAAsmoutput;const t:texceptiontemps;exceptlabel:tasmlabel); var paraloc1,paraloc2,paraloc3 : tcgpara; begin @@ -659,6 +663,33 @@ implementation end; + procedure location_get_data_ref(list:TAAsmoutput;const l:tlocation;var ref:treference;loadref:boolean); + begin + case l.loc of + LOC_REGISTER, + LOC_CREGISTER : + begin + if not loadref then + internalerror(200410231); + reference_reset_base(ref,l.register,0); + end; + LOC_REFERENCE, + LOC_CREFERENCE : + begin + if loadref then + begin + reference_reset_base(ref,cg.getaddressregister(list),0); + cg.a_load_ref_reg(list,OS_ADDR,OS_ADDR,l.reference,ref.base); + end + else + ref:=l.reference; + end; + else + internalerror(200309181); + end; + end; + + {***************************************************************************** Maybe_Save *****************************************************************************} @@ -686,11 +717,11 @@ implementation procedure copyvalueparas(p : tnamedindexitem;arg:pointer); var - href1 : treference; - list:TAAsmoutput; + href : treference; + hreg : tregister; + list : TAAsmoutput; hsym : tvarsym; l : longint; - loadref : boolean; localcopyloc : tlocation; begin list:=taasmoutput(arg); @@ -698,18 +729,7 @@ implementation (tvarsym(p).varspez=vs_value) and (paramanager.push_addr_param(tvarsym(p).varspez,tvarsym(p).vartype.def,current_procinfo.procdef.proccalloption)) then begin - loadref:=true; - case tvarsym(p).localloc.loc of - LOC_CREGISTER : - begin - reference_reset_base(href1,tvarsym(p).localloc.register,0); - loadref:=false; - end; - LOC_REFERENCE : - href1:=tvarsym(p).localloc.reference; - else - internalerror(200309181); - end; + location_get_data_ref(list,tvarsym(p).localloc,href,true); if is_open_array(tvarsym(p).vartype.def) or is_array_of_const(tvarsym(p).vartype.def) then begin @@ -720,7 +740,9 @@ implementation hsym:=tvarsym(tsym(p).owner.search('high'+p.name)); if not assigned(hsym) then internalerror(200306061); - cg.g_copyvaluepara_openarray(list,href1,hsym.localloc,tarraydef(tvarsym(p).vartype.def).elesize,loadref); + hreg:=cg.getaddressregister(list); + cg.g_copyvaluepara_openarray(list,href,hsym.localloc,tarraydef(tvarsym(p).vartype.def).elesize,hreg); + cg.a_load_reg_loc(list,OS_ADDR,hreg,tvarsym(p).localloc); end; end else @@ -737,10 +759,10 @@ 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,href1,localcopyloc.reference,tstringdef(tvarsym(p).vartype.def).len,loadref) + cg.g_copyshortstring(list,href,localcopyloc.reference,tstringdef(tvarsym(p).vartype.def).len) end else - cg.g_concatcopy(list,href1,localcopyloc.reference,tvarsym(p).vartype.def.size,loadref); + cg.g_concatcopy(list,href,localcopyloc.reference,tvarsym(p).vartype.def.size); { update localloc of varsym } tg.Ungetlocal(list,tvarsym(p).localloc.reference); tvarsym(p).localloc:=localcopyloc; @@ -751,9 +773,6 @@ implementation { initializes the regvars from staticsymtable with 0 } procedure initialize_regvars(p : tnamedindexitem;arg:pointer); - var - oldexprasmlist : TAAsmoutput; - hp : tnode; begin if (tsym(p).typ=varsym) then begin @@ -893,7 +912,7 @@ implementation var href : treference; tmpreg : tregister; - list:TAAsmoutput; + list : TAAsmoutput; begin list:=taasmoutput(arg); if (tsym(p).typ=varsym) and @@ -903,16 +922,15 @@ implementation case tvarsym(p).varspez of vs_value : begin - if tvarsym(p).localloc.loc<>LOC_REFERENCE then - internalerror(200309187); - cg.g_incrrefcount(list,tvarsym(p).vartype.def,tvarsym(p).localloc.reference,is_open_array(tvarsym(p).vartype.def)); + location_get_data_ref(list,tvarsym(p).localloc,href,is_open_array(tvarsym(p).vartype.def)); + cg.g_incrrefcount(list,tvarsym(p).vartype.def,href); end; vs_out : begin tmpreg:=cg.getaddressregister(list); cg.a_load_loc_reg(list,OS_ADDR,tvarsym(p).localloc,tmpreg); reference_reset_base(href,tmpreg,0); - cg.g_initialize(list,tvarsym(p).vartype.def,href,false); + cg.g_initialize(list,tvarsym(p).vartype.def,href); end; end; end; @@ -922,19 +940,20 @@ implementation { generates the code for decrementing the reference count of parameters } procedure final_paras(p : tnamedindexitem;arg:pointer); var - list:TAAsmoutput; + list : TAAsmoutput; + href : treference; begin list:=taasmoutput(arg); if (tsym(p).typ=varsym) and not is_class_or_interface(tvarsym(p).vartype.def) and tvarsym(p).vartype.def.needs_inittable then begin + location_get_data_ref(list,tvarsym(p).localloc,href,is_open_array(tvarsym(p).vartype.def)); if (tvarsym(p).varspez=vs_value) then begin include(current_procinfo.flags,pi_needs_implicit_finally); - if tvarsym(p).localloc.loc<>LOC_REFERENCE then - internalerror(200309188); - cg.g_decrrefcount(list,tvarsym(p).vartype.def,tvarsym(p).localloc.reference,is_open_array(tvarsym(p).vartype.def)); + location_get_data_ref(list,tvarsym(p).localloc,href,is_open_array(tvarsym(p).vartype.def)); + cg.g_decrrefcount(list,tvarsym(p).vartype.def,href); end; end else if (tsym(p).typ=varsym) and @@ -963,7 +982,7 @@ implementation hp^.def.needs_inittable then begin reference_reset_base(href,current_procinfo.framepointer,hp^.pos); - cg.g_initialize(list,hp^.def,href,false); + cg.g_initialize(list,hp^.def,href); end; hp:=hp^.next; end; @@ -983,7 +1002,7 @@ implementation begin include(current_procinfo.flags,pi_needs_implicit_finally); reference_reset_base(href,current_procinfo.framepointer,hp^.pos); - cg.g_finalize(list,hp^.def,href,false); + cg.g_finalize(list,hp^.def,href); end; hp:=hp^.next; end; @@ -1214,7 +1233,7 @@ implementation { use concatcopy, because it can also be a float which fails when load_ref_ref is used. Don't copy data when the references are equal } if not((href.base=ref.base) and (href.offset=ref.offset)) then - cg.g_concatcopy(list,href,ref,tcgsize2size[paraloc.size],false); + cg.g_concatcopy(list,href,ref,tcgsize2size[paraloc.size]); end; else internalerror(2002081302); @@ -1376,11 +1395,15 @@ implementation if assigned(current_module.globalsymtable) then tsymtable(current_module.globalsymtable).foreach_static({$ifndef TP}@{$endif}initialize_data,list); tsymtable(current_module.localsymtable).foreach_static({$ifndef TP}@{$endif}initialize_data,list); + tsymtable(current_module.localsymtable).foreach_static({$ifndef TP}@{$endif}initialize_regvars,list); end; { units have seperate code for initilization and finalization } potype_unitfinalize: ; { program init/final is generated in separate procedure } - potype_proginit: ; + potype_proginit: + begin + tsymtable(current_module.localsymtable).foreach_static({$ifndef TP}@{$endif}initialize_regvars,list); + end; else current_procinfo.procdef.localst.foreach_static({$ifndef TP}@{$endif}initialize_data,list); end; @@ -1391,10 +1414,6 @@ implementation { initialize ansi/widesstring para's } current_procinfo.procdef.parast.foreach_static({$ifndef TP}@{$endif}init_paras,list); - { initialize regvars in staticsymtable with 0, like .bss } - if current_procinfo.procdef.localst.symtabletype=staticsymtable then - current_procinfo.procdef.localst.foreach_static({$ifndef TP}@{$endif}initialize_regvars,list); - {$ifdef OLDREGVARS} load_regvars(list,nil); {$endif OLDREGVARS} @@ -2218,7 +2237,11 @@ implementation end. { $Log$ - Revision 1.229 2004-10-15 09:14:17 mazen + Revision 1.230 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.229 2004/10/15 09:14:17 mazen - remove $IFDEF DELPHI and related code - remove $IFDEF FPCPROCVAR and related code diff --git a/compiler/ncnv.pas b/compiler/ncnv.pas index bd9497d623..9609a32971 100644 --- a/compiler/ncnv.pas +++ b/compiler/ncnv.pas @@ -1507,14 +1507,10 @@ implementation end; end; - if (nf_explicit in flags) or - (nf_absolute in flags) then - begin - { check if the result could be in a register } - if not(tstoreddef(resulttype.def).is_intregable) and - not(tstoreddef(resulttype.def).is_fpuregable) then - make_not_regable(left); - end; + { check if the result could be in a register } + if not(tstoreddef(resulttype.def).is_intregable) and + not(tstoreddef(resulttype.def).is_fpuregable) then + make_not_regable(left); { now call the resulttype helper to do constant folding } result:=resulttype_call_helper(convtype); @@ -1996,6 +1992,11 @@ implementation ((convtype in [tc_int_2_bool,tc_bool_2_int]) and (nf_explicit in flags) and (resulttype.def.size=left.resulttype.def.size)); + + { When using only a part of the value it can't be in a register since + that will load the value in a new register first } + if (resulttype.def.sizecurrent_procinfo.procdef.localst.symtablelevel) then + ( + (symtable.symtablelevel<>current_procinfo.procdef.localst.symtablelevel) or + (current_procinfo.procdef.proctypeoption=potype_unitfinalize) + ) then make_not_regable(self); end; { fix self type which is declared as voidpointer in the @@ -1166,7 +1172,11 @@ begin end. { $Log$ - Revision 1.134 2004-10-12 14:35:14 peter + Revision 1.135 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.134 2004/10/12 14:35:14 peter * fixed crash when current_procinfo was not yet available Revision 1.133 2004/10/11 15:48:15 peter diff --git a/compiler/pdecsub.pas b/compiler/pdecsub.pas index cd6bd5c1b7..6f576264ce 100644 --- a/compiler/pdecsub.pas +++ b/compiler/pdecsub.pas @@ -341,7 +341,8 @@ implementation exit; with tvarsym(p) do begin - if paramanager.push_addr_param(varspez,vartype.def,tprocdef(arg).proccalloption) then + if not vartype.def.needs_inittable and + paramanager.push_addr_param(varspez,vartype.def,tprocdef(arg).proccalloption) then varregable:=vr_intreg; end; end; @@ -2266,7 +2267,11 @@ const end. { $Log$ - Revision 1.194 2004-10-15 09:14:17 mazen + Revision 1.195 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.194 2004/10/15 09:14:17 mazen - remove $IFDEF DELPHI and related code - remove $IFDEF FPCPROCVAR and related code diff --git a/compiler/rautils.pas b/compiler/rautils.pas index 39e0d5cbd4..b30c6b2617 100644 --- a/compiler/rautils.pas +++ b/compiler/rautils.pas @@ -858,6 +858,8 @@ Begin { that the variable is valid. } tvarsym(sym).varstate:=vs_used; inc(tvarsym(sym).refs); + { variable can't be placed in a register } + tvarsym(sym).varregable:=vr_none; case tvarsym(sym).owner.symtabletype of objectsymtable : begin @@ -903,8 +905,6 @@ Begin (current_procinfo.procdef.localst.symtablelevel>normal_function_level) and symtable_has_varsyms(current_procinfo.procdef.localst) then message1(asmr_e_local_para_unreachable,s); - { variable can't be placed in a register anymore } - tvarsym(sym).varregable:=vr_none; opr.localsym:=tvarsym(sym); opr.localsymofs:=0; opr.localindexreg:=indexreg; @@ -1664,7 +1664,11 @@ end; end. { $Log$ - Revision 1.91 2004-10-15 09:14:17 mazen + Revision 1.92 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.91 2004/10/15 09:14:17 mazen - remove $IFDEF DELPHI and related code - remove $IFDEF FPCPROCVAR and related code diff --git a/compiler/x86/cgx86.pas b/compiler/x86/cgx86.pas index 37ad56b7fc..8d647a0d7d 100644 --- a/compiler/x86/cgx86.pas +++ b/compiler/x86/cgx86.pas @@ -102,7 +102,7 @@ unit cgx86; procedure g_flags2reg(list: taasmoutput; size: TCgSize; const f: tresflags; reg: TRegister); override; procedure g_flags2ref(list: taasmoutput; size: TCgSize; const f: tresflags; const ref: TReference); override; - procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint; loadref : boolean);override; + procedure g_concatcopy(list : taasmoutput;const source,dest : treference;len : aint);override; { entry/exit code helpers } procedure g_releasevaluepara_openarray(list : taasmoutput;const ref:treference);override; @@ -1268,7 +1268,7 @@ unit cgx86; { ************* concatcopy ************ } - procedure Tcgx86.g_concatcopy(list:Taasmoutput;const source,dest:Treference;len:aint;loadref:boolean); + procedure Tcgx86.g_concatcopy(list:Taasmoutput;const source,dest:Treference;len:aint); const {$ifdef cpu64bit} @@ -1304,8 +1304,6 @@ unit cgx86; if (cs_littlesize in aktglobalswitches) and not((len<=16) and (cm=copy_mmx)) then cm:=copy_string; - if loadref then - cm:=copy_string; case cm of copy_move: begin @@ -1384,10 +1382,7 @@ unit cgx86; getcpuregister(list,REGDI); a_loadaddr_ref_reg(list,dest,REGDI); getcpuregister(list,REGSI); - if loadref then - a_load_ref_reg(list,OS_ADDR,OS_ADDR,source,REGSI) - else - a_loadaddr_ref_reg(list,source,REGSI); + a_loadaddr_ref_reg(list,source,REGSI); getcpuregister(list,REGCX); @@ -1679,7 +1674,11 @@ unit cgx86; end. { $Log$ - Revision 1.129 2004-10-06 19:27:35 jonas + Revision 1.130 2004-10-24 11:44:28 peter + * small regvar fixes + * loadref parameter removed from concatcopy,incrrefcount,etc + + Revision 1.129 2004/10/06 19:27:35 jonas * regvar fixes from Peter Revision 1.128 2004/10/05 20:41:02 peter