mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-21 18:09:30 +02:00
+ new integer regvar handling, should be much more efficient
This commit is contained in:
parent
72bc010795
commit
a8af566cd7
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user