+ new integer regvar handling, should be much more efficient

This commit is contained in:
Jonas Maebe 2000-12-05 11:44:32 +00:00
parent 72bc010795
commit a8af566cd7
13 changed files with 352 additions and 126 deletions

View File

@ -982,6 +982,7 @@ implementation
begin
pushusedregisters(pushedregs,$ff);
emit_ref(A_PUSH,S_L,newreference(ref));
saveregvars($ff);
if is_interfacecom(t) then
emitcall('FPC_INTF_INCR_REF')
else
@ -998,6 +999,7 @@ implementation
begin
pushusedregisters(pushedregs,$ff);
emitpushreferenceaddr(ref);
saveregvars($ff);
if is_interfacecom(t) then
begin
emitcall('FPC_INTF_DECR_REF');
@ -1033,6 +1035,7 @@ implementation
else
emitpushreferenceaddr(sref);
push_int(len);
saveregvars($ff);
emitcall('FPC_LONGSTR_COPY');
maybe_loadesi;
end;
@ -1046,6 +1049,7 @@ implementation
begin
pushusedregisters(pushedregs,$ff);
emitpushreferenceaddr(ref);
saveregvars($ff);
if is_ansistring(t) then
begin
emitcall('FPC_ANSISTR_INCR_REF');
@ -1067,6 +1071,7 @@ implementation
begin
pushusedregisters(pushedregs,$ff);
emitpushreferenceaddr(ref);
saveregvars($ff);
if is_ansistring(t) then
begin
emitcall('FPC_ANSISTR_DECR_REF');
@ -1608,6 +1613,7 @@ implementation
reset_reference(hr);
hr.symbol:=newasmsymbol(pvarsym(p)^.mangledname);
emitpushreferenceaddr(hr);
saveregvars($ff);
emitcall('FPC_INIT_THREADVAR');
end;
end;
@ -2949,7 +2955,10 @@ implementation
end.
{
$Log$
Revision 1.14 2000-11-29 00:30:43 florian
Revision 1.15 2000-12-05 11:44:32 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.14 2000/11/29 00:30:43 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -175,6 +175,7 @@ interface
emitpushreferenceaddr(location.reference);
emit_push_loc(right.location);
emit_push_loc(left.location);
saveregvars($ff);
emitcall('FPC_ANSISTR_CONCAT');
popusedregisters(pushedregs);
maybe_loadesi;
@ -244,6 +245,7 @@ interface
LOC_REGISTER,LOC_CREGISTER:
emit_reg(A_PUSH,S_L,left.location.register);
end;
saveregvars($ff);
emitcall('FPC_ANSISTR_COMPARE');
emit_reg_reg(A_OR,S_L,R_EAX,R_EAX);
popusedregisters(pushedregs);
@ -380,7 +382,7 @@ interface
regstopush := $ff;
remove_non_regvars_from_loc(right.location,
regstopush);
pushusedregisters(pushedregs,regstopush);
pushusedregisters(pushedregs,regstopush);
{ push the maximum possible length of the result }
{$ifdef newoptimizations2}
{ string (could be < 255 chars now) (JM) }
@ -394,6 +396,7 @@ interface
{ the pushref needs a "lea (..),edi; push edi") }
del_reference(right.location.reference);
emitpushreferenceaddr(right.location.reference);
saveregvars(regstopush);
{$ifdef newoptimizations2}
emitcall('FPC_SHORTSTR_CONCAT_LEN');
{$else newoptimizations2}
@ -443,6 +446,7 @@ interface
secondpass(right);
emitpushreferenceaddr(right.location.reference);
del_reference(right.location.reference);
saveregvars($ff);
emitcall('FPC_SHORTSTR_COMPARE');
maybe_loadesi;
popusedregisters(pushedregs);
@ -526,6 +530,7 @@ interface
emitpushreferenceaddr(left.location.reference);
emitpushreferenceaddr(right.location.reference);
End;
saveregvars($ff);
Case nodetype of
equaln, unequaln:
{$EndIf NoSetInclusion}
@ -573,6 +578,7 @@ interface
begin
pushsetelement(tunarynode(right).left);
emitpushreferenceaddr(href);
saveregvars(regstopush);
emitcall('FPC_SET_CREATE_ELEMENT');
end
else
@ -590,12 +596,14 @@ interface
pushsetelement(tbinarynode(right).right);
pushsetelement(tunarynode(right).left);
emitpushreferenceaddr(href);
saveregvars(regstopush);
emitcall('FPC_SET_SET_RANGE');
end
else
begin
pushsetelement(tunarynode(right).left);
emitpushreferenceaddr(href);
saveregvars(regstopush);
emitcall('FPC_SET_SET_BYTE');
end;
end
@ -611,6 +619,7 @@ interface
{$IfDef regallocfix}
del_location(left.location);
{$EndIf regallocfix}
saveregvars(regstopush);
emitcall('FPC_SET_ADD_SETS');
end;
end;
@ -641,6 +650,7 @@ interface
{ The same here }
del_location(left.location);
emitpushreferenceaddr(left.location.reference);
saveregvars(regstopush);
case nodetype of
subn : emitcall('FPC_SET_SUB_SETS');
symdifn : emitcall('FPC_SET_SYMDIF_SETS');
@ -1672,6 +1682,7 @@ interface
emit_pushq_loc(hloc);
clear_location(hloc);
emit_pushq_loc(right.location);
saveregvars($ff);
if porddef(resulttype)^.typ=u64bit then
emitcall('FPC_MUL_QWORD')
else
@ -2288,7 +2299,10 @@ begin
end.
{
$Log$
Revision 1.5 2000-11-29 00:30:45 florian
Revision 1.6 2000-12-05 11:44:32 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.5 2000/11/29 00:30:45 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -63,7 +63,7 @@ implementation
hcodegen,temp_gen,pass_2,
cpubase,cpuasm,
nmem,nld,
cgai386,tgcpu,n386ld,n386util;
cgai386,tgcpu,n386ld,n386util,regvars;
{*****************************************************************************
TI386CALLPARANODE
@ -266,10 +266,10 @@ implementation
{ we must pop this size also after !! }
{ must_pop : boolean; }
pop_size : longint;
pop_allowed : boolean;
pop_esp : boolean;
push_size : longint;
pop_esp : boolean;
pop_allowed : boolean;
regs_to_push : byte;
label
dont_call;
@ -341,14 +341,16 @@ implementation
iolabel:=nil;
{ save all used registers }
pushusedregisters(pushed,pprocdef(procdefinition)^.usedregisters);
regs_to_push := pprocdef(procdefinition)^.usedregisters;
pushusedregisters(pushed,regs_to_push);
{ give used registers through }
usedinproc:=usedinproc or pprocdef(procdefinition)^.usedregisters;
end
else
begin
pushusedregisters(pushed,$ff);
regs_to_push := $ff;
pushusedregisters(pushed,regs_to_push);
usedinproc:=$ff;
{ no IO check for methods and procedure variables }
iolabel:=nil;
@ -876,6 +878,8 @@ implementation
internalerror(25000);
end;
saveregvars(regs_to_push);
if (po_virtualmethod in procdefinition^.procoptions) and
not(no_virtual_call) then
begin
@ -1020,6 +1024,7 @@ implementation
emit_reg(A_PUSH,S_L,R_ESI);
end;
saveregvars($ff);
if hregister=R_NO then
emit_ref(A_CALL,S_NO,newreference(right.location.reference))
else
@ -1039,6 +1044,7 @@ implementation
end
else
begin
saveregvars($ff);
case right.location.loc of
LOC_REGISTER,LOC_CREGISTER:
begin
@ -1393,7 +1399,8 @@ implementation
oldunused,oldusableregs : tregisterset;
oldc_usableregs : longint;
oldreg_pushes : regvar_longintarray;
oldis_reg_var : regvar_booleanarray;
oldregvar_loaded,
oldis_reg_var : regvar_booleanarray;
{$ifdef TEMPREGDEBUG}
oldreg_user : regvar_ptreearray;
oldreg_releaser : regvar_ptreearray;
@ -1410,19 +1417,13 @@ implementation
with pregvarinfo(aktprocsym^.definition^.regvarinfo)^ do
for i := 1 to maxvarregs do
if assigned(regvars[i]) then
begin
case regsize(regvars[i]^.reg) of
S_B: tmpreg := reg8toreg32(regvars[i]^.reg);
S_W: tmpreg := reg16toreg32(regvars[i]^.reg);
S_L: tmpreg := regvars[i]^.reg;
end;
exprasmlist^.concat(new(pairegalloc,dealloc(tmpreg)));
end;
store_regvar(exprasmlist,regvars[i]^.reg);
oldunused := unused;
oldusableregs := usableregs;
oldc_usableregs := c_usableregs;
oldreg_pushes := reg_pushes;
oldis_reg_var := is_reg_var;
oldregvar_loaded := regvar_loaded;
{$ifdef TEMPREGDEBUG}
oldreg_user := reg_user;
oldreg_releaser := reg_releaser;
@ -1566,25 +1567,15 @@ implementation
{ procedure (JM) }
if assigned(aktprocsym^.definition^.regvarinfo) then
begin
with pregvarinfo(aktprocsym^.definition^.regvarinfo)^ do
for i := 1 to maxvarregs do
if assigned(regvars[i]) then
begin
case regsize(regvars[i]^.reg) of
S_B: tmpreg := reg8toreg32(regvars[i]^.reg);
S_W: tmpreg := reg16toreg32(regvars[i]^.reg);
S_L: tmpreg := regvars[i]^.reg;
end;
exprasmlist^.concat(new(pairegalloc,alloc(tmpreg)));
end;
oldunused := oldunused;
oldusableregs := oldusableregs;
oldc_usableregs := oldc_usableregs;
oldreg_pushes := oldreg_pushes;
oldis_reg_var := oldis_reg_var;
unused := oldunused;
usableregs := oldusableregs;
c_usableregs := oldc_usableregs;
reg_pushes := oldreg_pushes;
is_reg_var := oldis_reg_var;
regvar_loaded := oldregvar_loaded;
{$ifdef TEMPREGDEBUG}
oldreg_user := oldreg_user;
oldreg_releaser := oldreg_releaser;
reg_user := oldreg_user;
reg_releaser := oldreg_releaser;
{$endif TEMPREGDEBUG}
end;
end;
@ -1597,7 +1588,10 @@ begin
end.
{
$Log$
Revision 1.12 2000-12-03 22:26:54 florian
Revision 1.13 2000-12-05 11:44:33 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.12 2000/12/03 22:26:54 florian
* fixed web buzg 1275: problem with int64 functions results
Revision 1.11 2000/11/29 00:30:46 florian

View File

@ -279,6 +279,7 @@ implementation
release_loc(left.location);
emit_push_lea_loc(left.location,true);
emit_push_lea_loc(location,false);
saveregvars(regs_to_push);
emitcall('FPC_SHORTSTR_TO_ANSISTR');
maybe_loadesi;
popusedregisters(pushed);
@ -440,6 +441,7 @@ implementation
end;
push_int(arrsize);
push_int(strtype);
saveregvars(regstopush);
emitcall('FPC_STR_TO_CHARARRAY');
popusedregisters(pushedregs);
end;
@ -517,6 +519,7 @@ implementation
emit_push_lea_loc(left.location,true);
del_reference(left.location.reference);
emitpushreferenceaddr(location.reference);
saveregvars(regstopush);
emitcall('FPC_CHARARRAY_TO_SHORTSTR');
maybe_loadesi;
popusedregisters(pushed);
@ -532,6 +535,7 @@ implementation
emitpushreferenceaddr(left.location.reference);
release_loc(left.location);
emitpushreferenceaddr(location.reference);
saveregvars(regstopush);
emitcall('FPC_CHARARRAY_TO_ANSISTR');
popusedregisters(pushed);
maybe_loadesi;
@ -571,6 +575,7 @@ implementation
pushusedregisters(pushed,$ff);
emit_pushw_loc(left.location);
emitpushreferenceaddr(location.reference);
saveregvars($ff);
emitcall('FPC_CHAR_TO_ANSISTR');
popusedregisters(pushed);
maybe_loadesi;
@ -1102,6 +1107,7 @@ implementation
gettempofsizereference(32,href);
emit_push_mem_size(left.location.reference,4);
emitpushreferenceaddr(href);
saveregvars($ff);
emitcall('FPC_SET_LOAD_SMALL');
maybe_loadesi;
popusedregisters(pushedregs);
@ -1166,6 +1172,7 @@ implementation
end;
end;
emitpushreferenceaddr(location.reference);
saveregvars($ff);
emitcall('FPC_PCHAR_TO_SHORTSTR');
maybe_loadesi;
popusedregisters(pushed);
@ -1196,6 +1203,7 @@ implementation
end;
end;
emitpushreferenceaddr(location.reference);
saveregvars(regs_to_push);
emitcall('FPC_PCHAR_TO_ANSISTR');
maybe_loadesi;
popusedregisters(pushed);
@ -1419,6 +1427,7 @@ implementation
end;
else internalerror(100);
end;
saveregvars($ff);
emitcall('FPC_DO_IS');
emit_reg_reg(A_OR,S_B,R_AL,R_AL);
popusedregisters(pushed);
@ -1469,6 +1478,7 @@ implementation
end;
else internalerror(100);
end;
saveregvars($ff);
emitcall('FPC_DO_AS');
{ restore register, this restores automatically the }
{ result }
@ -1483,7 +1493,10 @@ begin
end.
{
$Log$
Revision 1.8 2000-11-29 00:30:46 florian
Revision 1.9 2000-12-05 11:44:33 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.8 2000/11/29 00:30:46 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -90,7 +90,7 @@ implementation
hcodegen,temp_gen,pass_2,
cpubase,cpuasm,
pass_1,nld,ncon,
cgai386,tgcpu,n386util;
cgai386,tgcpu,n386util,regvars;
{*****************************************************************************
Second_While_RepeatN
@ -102,6 +102,9 @@ implementation
oldclabel,oldblabel : pasmlabel;
otlabel,oflabel : pasmlabel;
start_regvars_loaded,
then_regvars_loaded: regvar_booleanarray;
begin
getlabel(lloop);
getlabel(lcont);
@ -110,10 +113,11 @@ implementation
oldclabel:=aktcontinuelabel;
oldblabel:=aktbreaklabel;
load_all_regvars(exprasmlist);
{ handling code at the end as it is much more efficient, and makes
while equal to repeat loop, only the end true/false is swapped (PFV) }
if nodetype=whilen then
emitjmp(C_None,lcont);
emitjmp(C_None,lcont);
emitlab(lloop);
@ -122,6 +126,9 @@ implementation
cleartempgen;
if assigned(right) then
secondpass(right);
load_all_regvars(exprasmlist);
emitlab(lcont);
otlabel:=truelabel;
oflabel:=falselabel;
@ -138,11 +145,15 @@ implementation
end;
cleartempgen;
secondpass(left);
load_all_regvars(exprasmlist);
maketojumpbool(left);
emitlab(lbreak);
truelabel:=otlabel;
falselabel:=oflabel;
aktcontinuelabel:=oldclabel;
aktbreaklabel:=oldblabel;
{ a break/continue in a while/repeat block can't be seen outside }
@ -166,12 +177,15 @@ implementation
getlabel(falselabel);
cleartempgen;
secondpass(left);
load_all_regvars(exprasmlist);
maketojumpbool(left);
if assigned(right) then
begin
emitlab(truelabel);
cleartempgen;
secondpass(right);
{ automatically done for blocks, but not for statements (JM) }
load_all_regvars(exprasmlist);
end;
if assigned(t1) then
begin
@ -185,6 +199,7 @@ implementation
emitlab(falselabel);
cleartempgen;
secondpass(t1);
load_all_regvars(exprasmlist);
if assigned(right) then
emitlab(hl);
end
@ -324,6 +339,8 @@ implementation
else
hcond:=C_A;
load_all_regvars(exprasmlist);
if not(omitfirstcomp) or temptovalue then
emitjmp(hcond,aktbreaklabel);
@ -336,7 +353,10 @@ implementation
{ help register must not be in instruction block }
cleartempgen;
if assigned(t1) then
secondpass(t1);
begin
secondpass(t1);
load_all_regvars(exprasmlist);
end;
emitlab(aktcontinuelabel);
@ -390,6 +410,7 @@ implementation
hcond:=C_GE
else
hcond:=C_AE;
load_all_regvars(exprasmlist);
emitjmp(hcond,aktbreaklabel);
{ according to count direction DEC or INC... }
{ must be after the test because of 0 to 255 for bytes !! }
@ -434,6 +455,7 @@ implementation
label
do_jmp;
begin
load_all_regvars(exprasmlist);
include(flowcontrol,fc_exit);
if assigned(left) then
if left.nodetype=assignn then
@ -541,9 +563,7 @@ do_jmp:
emitjmp(C_None,aktexit2label);
end
else
begin
emitjmp(C_None,aktexitlabel);
end;
emitjmp(C_None,aktexitlabel);
end;
@ -555,7 +575,10 @@ do_jmp:
begin
include(flowcontrol,fc_break);
if aktbreaklabel<>nil then
emitjmp(C_None,aktbreaklabel)
begin
load_all_regvars(exprasmlist);
emitjmp(C_None,aktbreaklabel)
end
else
CGMessage(cg_e_break_not_allowed);
end;
@ -569,7 +592,10 @@ do_jmp:
begin
include(flowcontrol,fc_continue);
if aktcontinuelabel<>nil then
emitjmp(C_None,aktcontinuelabel)
begin
load_all_regvars(exprasmlist);
emitjmp(C_None,aktcontinuelabel)
end
else
CGMessage(cg_e_continue_not_allowed);
end;
@ -582,6 +608,7 @@ do_jmp:
procedure ti386gotonode.pass_2;
begin
load_all_regvars(exprasmlist);
emitjmp(C_None,labelnr);
{ the assigned avoids only crashes if the label isn't defined }
if assigned(labsym) and
@ -597,6 +624,7 @@ do_jmp:
procedure ti386labelnode.pass_2;
begin
load_all_regvars(exprasmlist);
emitlab(labelnr);
cleartempgen;
secondpass(left);
@ -1284,7 +1312,10 @@ begin
end.
{
$Log$
Revision 1.3 2000-11-29 00:30:47 florian
Revision 1.4 2000-12-05 11:44:33 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.3 2000/11/29 00:30:47 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -379,6 +379,7 @@ implementation
{ reset and rewrite to the inline list a call }
{ allways read only one record by element }
push_int(typedtyp^.size);
saveregvars($ff);
if doread then
emitcall('FPC_TYPED_READ')
else
@ -434,6 +435,7 @@ implementation
if pararesult^.deftype=floatdef then
push_int(ord(orgfloattype));
end;
saveregvars($ff);
case pararesult^.deftype of
stringdef :
begin
@ -501,6 +503,7 @@ implementation
begin
pushusedregisters(pushed,$ff);
emit_push_mem(aktfile);
saveregvars($ff);
if doread then
begin
if doln then
@ -649,6 +652,7 @@ implementation
if codegenerror then
exit;
saveregvars($ff);
if is_real then
emitcall(procedureprefix+'FLOAT')
else
@ -778,6 +782,8 @@ implementation
procedureprefix := 'FPC_VAL_UINT_';
end;
End;
saveregvars($ff);
emitcall(procedureprefix+pstringdef(node.resulttype)^.stringtypname);
{ before disposing node we need to ungettemp !! PM }
if node.left.location.loc in [LOC_REFERENCE,LOC_MEM] then
@ -1341,6 +1347,7 @@ implementation
if codegenerror then
exit;
emitpushreferenceaddr(tcallparanode(left).left.location.reference);
saveregvars($ff);
if assigned(tcallparanode(left).right) then
emitcall('FPC_FINALIZEARRAY')
else
@ -1373,6 +1380,7 @@ implementation
emit_const(A_PUSH,S_L,pfiledef(left.resulttype)^.typedfiletype.def^.size);
secondpass(left);
emitpushreferenceaddr(left.location.reference);
saveregvars($ff);
if inlinenumber=in_reset_typedfile then
emitcall('FPC_RESET_TYPED')
else
@ -1436,6 +1444,7 @@ implementation
hr2.symbol:=pstoreddef(def)^.get_inittable_label;
emitpushreferenceaddr(hr2);
emitpushreferenceaddr(tcallparanode(hp).left.location.reference);
saveregvars($ff);
emitcall('FPC_DYNARR_SETLENGTH');
ungetiftemp(hr);
end
@ -1446,15 +1455,20 @@ implementation
st_widestring:
begin
emitpushreferenceaddr(tcallparanode(hp).left.location.reference);
saveregvars($ff);
emitcall('FPC_WIDESTR_SETLENGTH');
end;
st_ansistring:
begin
emitpushreferenceaddr(tcallparanode(hp).left.location.reference);
saveregvars($ff);
emitcall('FPC_ANSISTR_SETLENGTH');
end;
st_shortstring:
emitcall('FPC_SHORTSTR_SETLENGTH');
begin
saveregvars($ff);
emitcall('FPC_SHORTSTR_SETLENGTH');
end;
end;
end;
popusedregisters(pushed);
@ -1503,8 +1517,11 @@ implementation
end
else
{ LOC_CREGISTER }
emit_const_reg(asmop,S_L,
l,tcallparanode(left).left.location.register);
begin
secondpass(tcallparanode(left).left);
emit_const_reg(asmop,S_L,
l,tcallparanode(left).left.location.register);
end;
end
else
begin
@ -1665,7 +1682,10 @@ begin
end.
{
$Log$
Revision 1.7 2000-11-29 00:30:47 florian
Revision 1.8 2000-12-05 11:44:33 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.7 2000/11/29 00:30:47 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -55,7 +55,7 @@ implementation
hcodegen,temp_gen,pass_2,
nmem,ncon,ncnv,
cpubase,cpuasm,
cgai386,tgcpu,n386cnv,n386util;
cgai386,tgcpu,n386cnv,n386util,regvars;
{*****************************************************************************
SecondLoad
@ -154,11 +154,20 @@ implementation
location.register:=pvarsym(symtableentry)^.reg;
end
else
if not(makereg32(pvarsym(symtableentry)^.reg) in [R_EAX..R_EBX]) or
regvar_loaded[pvarsym(symtableentry)^.reg] then
begin
location.loc:=LOC_CREGISTER;
location.register:=pvarsym(symtableentry)^.reg;
unused:=unused-[pvarsym(symtableentry)^.reg];
end;
end
else
begin
load_regvar(exprasmlist,pvarsym(symtableentry));
location.loc:=LOC_CREGISTER;
location.register:=pvarsym(symtableentry)^.reg;
unused:=unused-[pvarsym(symtableentry)^.reg];
end
end
else
begin
@ -407,6 +416,7 @@ implementation
getlabel(truelabel);
getlabel(falselabel);
{ calculate left sides }
{ don't do it yet if it's a crgister (JM) }
if not(nf_concat_string in flags) then
secondpass(left);
@ -498,6 +508,7 @@ implementation
end;
emitpushreferenceaddr(left.location.reference);
del_reference(left.location.reference);
saveregvars($ff);
emitcall('FPC_ANSISTR_ASSIGN');
maybe_loadesi;
popusedregisters(regspushed);
@ -1050,7 +1061,10 @@ begin
end.
{
$Log$
Revision 1.9 2000-11-29 00:30:48 florian
Revision 1.10 2000-12-05 11:44:33 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.9 2000/11/29 00:30:48 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -110,6 +110,7 @@ implementation
opname:='DIV_'
else
opname:='MOD_';
saveregvars($ff);
emitcall('FPC_'+opname+typename);
emit_reg_reg(A_MOV,S_L,R_EAX,location.registerlow);
@ -995,7 +996,10 @@ begin
end.
{
$Log$
Revision 1.7 2000-11-29 00:30:48 florian
Revision 1.8 2000-12-05 11:44:33 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.7 2000/11/29 00:30:48 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -142,6 +142,7 @@ implementation
{ determines the size of the mem block }
push_int(ppointerdef(resulttype)^.pointertype.def^.size);
emit_push_lea_loc(location,false);
saveregvars($ff);
emitcall('FPC_GETMEM');
if ppointerdef(resulttype)^.pointertype.def^.needs_inittable then
@ -212,7 +213,8 @@ implementation
exit;
pushusedregisters(pushed,$ff);
saveregvars($ff);
{ call the mem handling procedures }
case nodetype of
simpledisposen:
@ -481,6 +483,7 @@ implementation
end;
pushusedregisters(pushed,$ff);
emitpushreferenceaddr(left.location.reference);
saveregvars($ff);
if is_ansistring(left.resulttype) then
emitcall('FPC_ANSISTR_UNIQUE')
else
@ -508,6 +511,7 @@ implementation
begin
pushusedregisters(pushed,$ff);
emit_reg(A_PUSH,S_L,location.reference.base);
saveregvars($ff);
emitcall('FPC_ANSISTR_CHECKZERO');
maybe_loadesi;
popusedregisters(pushed);
@ -552,6 +556,7 @@ implementation
begin
pushusedregisters(pushed,$ff);
emit_reg(A_PUSH,S_L,location.reference.base);
saveregvars($ff);
emitcall('FPC_ANSISTR_CHECKZERO');
maybe_loadesi;
popusedregisters(pushed);
@ -612,6 +617,7 @@ implementation
hp:=newreference(location.reference);
dec(hp^.offset,7);
emit_ref(A_PUSH,S_L,hp);
saveregvars($ff);
emitcall('FPC_ANSISTR_RANGECHECK');
popusedregisters(pushed);
maybe_loadesi;
@ -834,6 +840,7 @@ implementation
hp:=newreference(location.reference);
dec(hp^.offset,7);
emit_ref(A_PUSH,S_L,hp);
saveregvars($ff);
emitcall('FPC_ANSISTR_RANGECHECK');
popusedregisters(pushed);
maybe_loadesi;
@ -1053,7 +1060,10 @@ begin
end.
{
$Log$
Revision 1.6 2000-11-29 00:30:48 florian
Revision 1.7 2000-12-05 11:44:33 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.6 2000/11/29 00:30:48 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -50,7 +50,7 @@ implementation
hcodegen,temp_gen,pass_2,
ncon,
cpubase,
cgai386,tgcpu,n386util;
cgai386,tgcpu,n386util,regvars;
const
bytes2Sxx:array[1..8] of Topsize=(S_B,S_W,S_NO,S_L,S_NO,S_NO,S_NO,S_Q);
@ -950,6 +950,8 @@ implementation
{ we need the min_label always to choose between }
{ cmps and subs/decs }
min_label:=case_get_min(nodes);
load_all_regvars(exprasmlist);
{ now generate the jumps }
if opsize=S_Q then
genlinearcmplist(nodes)
@ -1046,6 +1048,7 @@ implementation
secondpass(tbinarynode(hp).right);
{ don't come back to case line }
aktfilepos:=exprasmlist^.getlasttaifilepos^;
load_all_regvars(exprasmlist);
emitjmp(C_None,endlabel);
hp:=tbinarynode(hp).left;
end;
@ -1055,6 +1058,7 @@ implementation
begin
cleartempgen;
secondpass(elseblock);
load_all_regvars(exprasmlist);
end;
emitlab(endlabel);
end;
@ -1067,7 +1071,10 @@ begin
end.
{
$Log$
Revision 1.6 2000-11-29 00:30:49 florian
Revision 1.7 2000-12-05 11:44:34 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.6 2000/11/29 00:30:49 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -64,7 +64,7 @@ implementation
ncon,nld,
pass_1,pass_2,
hcodegen,tgcpu,temp_gen,
cgai386;
cgai386,regvars;
{*****************************************************************************
@ -79,6 +79,11 @@ implementation
href : treference;
{$endif TEMPS_NOT_PUSH}
begin
if p.location.loc = LOC_CREGISTER then
begin
maybe_push := true;
exit;
end;
if needed>usablereg32 then
begin
if (p.location.loc=LOC_REGISTER) then
@ -196,6 +201,11 @@ implementation
href : treference;
{$endif TEMPS_NOT_PUSH}
begin
if p.location.loc = LOC_CREGISTER then
begin
load_regvar_reg(exprasmlist,p.location.register);
exit;
end;
hregister:=getregister32;
{$ifdef TEMPS_NOT_PUSH}
reset_reference(href);
@ -857,6 +867,7 @@ implementation
aktfilepos:=p.fileinfo;
if is_boolean(p.resulttype) then
begin
load_all_regvars(exprasmlist);
if is_constboolnode(p) then
begin
if tordconstnode(p).value<>0 then
@ -1416,6 +1427,7 @@ implementation
end;
push_shortstring_length(dest);
emitpushreferenceaddr(dest.location.reference);
saveregvars($ff);
emitcall('FPC_ANSISTR_TO_SHORTSTR');
popusedregisters(pushed);
maybe_loadesi;
@ -1460,6 +1472,7 @@ implementation
end;
emitpushreferenceaddr(p.left.location.reference);
del_reference(p.left.location.reference);
saveregvars($ff);
emitcall('FPC_INTF_ASSIGN');
maybe_loadesi;
popusedregisters(pushed);
@ -1472,7 +1485,10 @@ implementation
end.
{
$Log$
Revision 1.5 2000-11-29 00:30:49 florian
Revision 1.6 2000-12-05 11:44:34 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.5 2000/11/29 00:30:49 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -75,6 +75,9 @@ interface
procedure pushusedregisters(var pushed : tpushed;b : byte);
procedure popusedregisters(const pushed : tpushed);
{ saves register variables (restoring happens automatically (JM) }
procedure saveregvars(b: byte);
{ saves and restores used registers to temp. values }
procedure saveusedregisters(var saved : tsaved;b : byte);
procedure restoreusedregisters(const saved : tsaved);
@ -112,6 +115,8 @@ interface
{ variable }
reg_pushes : regvar_longintarray;
is_reg_var : regvar_booleanarray;
regvar_loaded: regvar_booleanarray;
{$ifdef TEMPREGDEBUG}
reg_user : regvar_ptreearray;
reg_releaser : regvar_ptreearray;
@ -121,7 +126,7 @@ interface
implementation
uses
globtype,temp_gen;
globtype,temp_gen,regvars;
procedure incrementregisterpushed(b : byte);
@ -151,8 +156,9 @@ implementation
{ if the register is used by the calling subroutine }
if ((b and ($80 shr byte(r)))<>0) then
begin
{ and is present in use }
if not(r in unused) then
{ and is present in use }
if not is_reg_var[r] then
if not(r in unused) then
begin
{ then save it }
exprasmlist^.concat(new(paicpu,op_reg(A_PUSH,S_L,r)));
@ -204,6 +210,22 @@ implementation
{$endif TEMPREGDEBUG}
end;
procedure saveregvars(b: byte);
var
r : tregister;
begin
if not(cs_regalloc in aktglobalswitches) then
exit;
for r:=R_EAX to R_EBX do
{ if the register is used by the calling subroutine }
if ((b and ($80 shr byte(r)))<>0) and is_reg_var[r] then
store_regvar(exprasmlist,r)
end;
procedure saveusedregisters(var saved : tsaved;b : byte);
var
@ -645,6 +667,8 @@ implementation
usableregs:=[R_EAX,R_EBX,R_ECX,R_EDX];
c_usableregs:=4;
{$endif SUPPORT_MMX}
fillchar(regvar_loaded,sizeof(regvar_loaded),false);
fillchar(is_reg_var,sizeof(is_reg_var),false);
fpuvaroffset:=0;
end;
@ -653,7 +677,10 @@ begin
end.
{
$Log$
Revision 1.1 2000-11-29 00:30:51 florian
Revision 1.2 2000-12-05 11:44:34 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.1 2000/11/29 00:30:51 florian
* unused units removed from uses clause
* some changes for widestrings

View File

@ -28,20 +28,27 @@ interface
uses
aasm,
node;
node,
symsym,
cpubase;
procedure assign_regvars(p: tnode);
procedure load_regvars(asml: paasmoutput; p: tnode);
procedure cleanup_regvars(asml: paasmoutput);
{$ifdef i386}
procedure store_regvar(asml: paasmoutput; reg: tregister);
procedure load_regvar(asml: paasmoutput; vsym: pvarsym);
procedure load_regvar_reg(asml: paasmoutput; reg: tregister);
procedure load_all_regvars(asml: paasmoutput);
{$endif i386}
implementation
uses
globtype,systems,comphook,
cutils,cobjects,verbose,globals,
symconst,symbase,symtype,symdef,symsym,types,
hcodegen,cpubase,cpuasm,tgcpu;
symconst,symbase,symtype,symdef,types,
hcodegen,cpuasm,tgcpu;
var
@ -278,16 +285,118 @@ implementation
end;
{$ifdef i386}
procedure store_regvar(asml: paasmoutput; reg: tregister);
var
i: longint;
hr: preference;
regvarinfo: pregvarinfo;
vsym: pvarsym;
begin
regvarinfo := pregvarinfo(aktprocsym^.definition^.regvarinfo);
if not assigned(regvarinfo) then
exit;
for i := 1 to maxvarregs do
if assigned(regvarinfo^.regvars[i]) and
(reg32(regvarinfo^.regvars[i]^.reg) = reg) then
begin
if regvar_loaded[reg32(reg)] then
begin
vsym := pvarsym(regvarinfo^.regvars[i]);
new(hr);
reset_reference(hr^);
if vsym^.owner^.symtabletype in [inlinelocalsymtable,localsymtable] then
hr^.offset:=-vsym^.address+vsym^.owner^.address_fixup
else hr^.offset:=vsym^.address+vsym^.owner^.address_fixup;
hr^.base:=procinfo^.framepointer;
asml^.concat(new(paicpu,op_reg_ref(A_MOV,regsize(vsym^.reg),vsym^.reg,hr)));
asml^.concat(new(pairegalloc,dealloc(reg32(reg))));
regvar_loaded[reg32(reg)] := false;
end;
break;
end;
end;
procedure load_regvar(asml: paasmoutput; vsym: pvarsym);
var
hr: preference;
opsize: topsize;
opcode: tasmop;
begin
if not regvar_loaded[reg32(vsym^.reg)] then
begin
asml^.concat(new(pairegalloc,alloc(reg32(vsym^.reg))));
{ zero the regvars because the upper 48bits must be clear }
{ for 8bits vars when using them with btrl }
{ don't care about sign extension, since the upper 24/16 }
{ bits won't be adapted when doing maths anyway (JM) }
case regsize(vsym^.reg) of
S_L:
begin
opsize := S_L;
opcode := A_MOV;
end;
S_W:
begin
opsize := S_WL;
opcode := A_MOVZX;
end;
S_B:
begin
opsize := S_BL;
opcode := A_MOVZX;
end;
end;
asml^.concat(new(pairegalloc,alloc(reg32(vsym^.reg))));
new(hr);
reset_reference(hr^);
if vsym^.owner^.symtabletype in [inlinelocalsymtable,localsymtable] then
hr^.offset:=-vsym^.address+vsym^.owner^.address_fixup
else hr^.offset:=vsym^.address+vsym^.owner^.address_fixup;
hr^.base:=procinfo^.framepointer;
asml^.concat(new(paicpu,op_ref_reg(opcode,opsize,hr,reg32(vsym^.reg))));
regvar_loaded[reg32(vsym^.reg)] := true;
end;
end;
procedure load_regvar_reg(asml: paasmoutput; reg: tregister);
var
i: longint;
regvarinfo: pregvarinfo;
vsym: pvarsym;
begin
regvarinfo := pregvarinfo(aktprocsym^.definition^.regvarinfo);
if not assigned(regvarinfo) then
exit;
reg := reg32(reg);
for i := 1 to maxvarregs do
if assigned(regvarinfo^.regvars[i]) and
(reg32(regvarinfo^.regvars[i]^.reg) = reg) then
load_regvar(asml,pvarsym(regvarinfo^.regvars[i]))
end;
procedure load_all_regvars(asml: paasmoutput);
var
i: longint;
regvarinfo: pregvarinfo;
begin
regvarinfo := pregvarinfo(aktprocsym^.definition^.regvarinfo);
if not assigned(regvarinfo) then
exit;
for i := 1 to maxvarregs do
if assigned(regvarinfo^.regvars[i]) and
(reg32(regvarinfo^.regvars[i]^.reg) in [R_EAX,R_EBX,R_ECX,R_EDX]) then
load_regvar(asml,pvarsym(regvarinfo^.regvars[i]))
end;
{$endif i386}
procedure load_regvars(asml: paasmoutput; p: tnode);
var
i: longint;
hr : preference;
regvarinfo: pregvarinfo;
{$ifdef i386}
opsize: topsize;
opcode: tasmop;
signed: boolean;
{$endif i386}
begin
if (cs_regalloc in aktglobalswitches) and
((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
@ -296,14 +405,12 @@ implementation
{ can happen when inlining assembler procedures (JM) }
if not assigned(regvarinfo) then
exit;
{$ifdef m68k}
for i:=1 to maxvarregs do
begin
{ parameter must be load }
if regvarinfo^.regvars_para[i] then
begin
{$ifdef i386}
asml^.concat(new(pairegalloc,alloc(reg32(regvarinfo^.regvars[i]^.reg))));
{$endif i386}
{ procinfo is there actual, }
{ because we can't never be in a }
{ nested procedure }
@ -312,65 +419,21 @@ implementation
reset_reference(hr^);
hr^.offset:=pvarsym(regvarinfo^.regvars[i])^.address+procinfo^.para_offset;
hr^.base:=procinfo^.framepointer;
{$ifdef i386}
{ zero the regvars because the upper 48bits must be clear }
{ for 8bits vars when using them with btrl (JM) }
signed :=
(pvarsym(regvarinfo^.regvars[i])^.vartype.def^.deftype =
orddef) and
is_signed(pvarsym(regvarinfo^.regvars[i])^.vartype.def);
case regsize(regvarinfo^.regvars[i]^.reg) of
S_L:
begin
opsize := S_L;
opcode := A_MOV;
end;
S_W:
begin
opsize := S_WL;
if signed then
opcode := A_MOVSX
else opcode := A_MOVZX;
end;
S_B:
begin
opsize := S_BL;
if signed then
opcode := A_MOVSX
else opcode := A_MOVZX;
end;
end;
asml^.concat(new(paicpu,op_ref_reg(opcode,opsize,
hr,reg32(regvarinfo^.regvars[i]^.reg))));
{$endif i386}
{$ifdef m68k}
asml^.concat(new(paicpu,op_ref_reg(A_MOVE,regsize(regvarinfo^.regvars[i]^.reg),
hr,regvarinfo^.regvars[i]^.reg)));
{$endif m68k}
end
end;
{$endif m68k}
for i:=1 to maxvarregs do
begin
if assigned(regvarinfo^.regvars[i]) then
begin
{$ifdef i386}
if not(regvarinfo^.regvars_para[i]) then
begin
asml^.concat(new(pairegalloc,alloc(reg32(regvarinfo^.regvars[i]^.reg))));
{ zero the regvars because the upper 48bits must be clear }
{ for 8bits vars when using them with btrl (JM) }
if (regsize(regvarinfo^.regvars[i]^.reg) in [S_B,S_W]) then
asml^.concat(new(paicpu,op_reg_reg(A_XOR,S_L,
reg32(regvarinfo^.regvars[i]^.reg),
reg32(regvarinfo^.regvars[i]^.reg))));
end;
{$endif i386}
if cs_asm_source in aktglobalswitches then
asml^.insert(new(pai_asm_comment,init(strpnew(regvarinfo^.regvars[i]^.name+
asml^.insert(new(pai_asm_comment,init(strpnew(regvarinfo^.regvars[i]^.name+
' with weight '+tostr(regvarinfo^.regvars[i]^.refs)+' assigned to register '+
reg2str(regvarinfo^.regvars[i]^.reg)))));
if (status.verbosity and v_debug)=v_debug then
Message3(cg_d_register_weight,reg2str(regvarinfo^.regvars[i]^.reg),
Message3(cg_d_register_weight,reg2str(regvarinfo^.regvars[i]^.reg),
tostr(regvarinfo^.regvars[i]^.refs),regvarinfo^.regvars[i]^.name);
end;
end;
@ -447,7 +510,8 @@ implementation
{ ... and clean it up }
asml^.concat(new(paicpu,op_reg(A_FSTP,S_NO,R_ST0)));
for i := 1 to maxvarregs do
if assigned(regvars[i]) then
if assigned(regvars[i]) and
(regvar_loaded[reg32(regvars[i]^.reg)]) then
asml^.concat(new(pairegalloc,dealloc(reg32(regvars[i]^.reg))));
end;
{$endif i386}
@ -457,7 +521,10 @@ end.
{
$Log$
Revision 1.13 2000-11-29 00:30:39 florian
Revision 1.14 2000-12-05 11:44:32 jonas
+ new integer regvar handling, should be much more efficient
Revision 1.13 2000/11/29 00:30:39 florian
* unused units removed from uses clause
* some changes for widestrings