* regvar fixes

This commit is contained in:
peter 2003-05-16 14:33:31 +00:00
parent 1d3a842c07
commit abca40f041
12 changed files with 373 additions and 222 deletions

View File

@ -63,6 +63,10 @@
'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7' 'xmm0','xmm1','xmm2','xmm3','xmm4','xmm5','xmm6','xmm7'
); );
{*****************************************************************************
Constants
*****************************************************************************}
firstsaveintreg = RS_EAX; firstsaveintreg = RS_EAX;
lastsaveintreg = RS_EDX; lastsaveintreg = RS_EDX;
firstsavefpureg = R_NO; firstsavefpureg = R_NO;
@ -70,6 +74,34 @@
firstsavemmreg = R_MM0; firstsavemmreg = R_MM0;
lastsavemmreg = R_MM7; lastsavemmreg = R_MM7;
general_registers = [R_EAX,R_EBX,R_ECX,R_EDX];
general_superregisters = [RS_EAX,RS_EBX,RS_ECX,RS_EDX];
{$ifdef newra}
usableregsint = [first_imreg..last_imreg];
{$else}
usableregsint = [RS_EAX,RS_EBX,RS_ECX,RS_EDX];
{$endif}
c_countusableregsint = 4;
maxaddrregs = 1;
addrregs = [R_ESI];
usableregsaddr = [RS_ESI];
c_countusableregsaddr = 1;
maxvarregs = 4;
varregs : array[1..maxvarregs] of tnewregister =
(RS_EBX,RS_EDX,RS_ECX,RS_EAX);
maxfpuvarregs = 8;
{# Registers which are defined as scratch and no need to save across
routine calls or in assembler blocks.
}
{$ifndef newra}
max_scratch_regs = 1;
scratch_regs : array[1..max_scratch_regs] of Tsuperregister = (RS_EDI);
{$endif}
{***************************************************************************** {*****************************************************************************
GDB Information GDB Information
*****************************************************************************} *****************************************************************************}
@ -170,7 +202,13 @@
{ {
$Log$ $Log$
Revision 1.1 2003-04-25 11:12:09 florian Revision 1.3 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.2 2002/04/25 16:12:09 florian
* fixed more problems with cpubase and x86-64
Revision 1.1 2003/04/25 11:12:09 florian
* merged i386/cpubase and x86_64/cpubase to x86/cpubase; * merged i386/cpubase and x86_64/cpubase to x86/cpubase;
different stuff went to cpubase.inc different stuff went to cpubase.inc
} }

View File

@ -105,7 +105,7 @@ begin
if (p.ops = 1) then if (p.ops = 1) then
begin begin
r.enum:=R_EDX; r.enum:=R_EDX;
if rg.is_reg_var[R_EDX] and if (RS_EDX in rg.is_reg_var_int) and
(not getNextInstruction(p,hp) or (not getNextInstruction(p,hp) or
not((hp.typ = ait_instruction) and not((hp.typ = ait_instruction) and
(hp.opcode = A_MOV) and (hp.opcode = A_MOV) and
@ -125,7 +125,7 @@ begin
else else
{ only possible for imul } { only possible for imul }
{ last operand is always destination } { last operand is always destination }
if rg.is_reg_var[reg32(p.oper[p.ops-1].reg).enum] then if ((p.oper[p.ops-1].reg.number shr 8) in rg.is_reg_var_int) then
for regCounter.enum := R_EAX to R_EDI do for regCounter.enum := R_EAX to R_EDI do
begin begin
if writeDestroysContents(p.oper[p.ops-1],regCounter,c[regCounter.enum]) then if writeDestroysContents(p.oper[p.ops-1],regCounter,c[regCounter.enum]) then
@ -1997,7 +1997,10 @@ End.
{ {
$Log$ $Log$
Revision 1.44 2003-04-27 11:21:35 peter Revision 1.45 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.44 2003/04/27 11:21:35 peter
* aktprocdef renamed to current_procdef * aktprocdef renamed to current_procdef
* procinfo renamed to current_procinfo * procinfo renamed to current_procinfo
* procinfo will now be stored in current_module so it can be * procinfo will now be stored in current_module so it can be

View File

@ -64,7 +64,7 @@ unit rgcpu;
const s:Tsupregset); const s:Tsupregset);
{$ifdef SUPPORT_MMX} {$ifdef SUPPORT_MMX}
procedure pushusedotherregisters(list:Taasmoutput; procedure pushusedotherregisters(list:Taasmoutput;
var pushed:Tpushedsaved; var pushed:Tpushedsavedother;
const s:Tregisterset); const s:Tregisterset);
{$endif SUPPORT_MMX} {$endif SUPPORT_MMX}
@ -72,19 +72,19 @@ unit rgcpu;
const pushed:Tpushedsavedint); const pushed:Tpushedsavedint);
{$ifdef SUPPORT_MMX} {$ifdef SUPPORT_MMX}
procedure popusedotherregisters(list:Taasmoutput; procedure popusedotherregisters(list:Taasmoutput;
const pushed:Tpushedsaved); const pushed:Tpushedsavedother);
{$endif SUPPORT_MMX} {$endif SUPPORT_MMX}
procedure saveusedintregisters(list:Taasmoutput; procedure saveusedintregisters(list:Taasmoutput;
var saved:Tpushedsavedint; var saved:Tpushedsavedint;
const s:Tsupregset);override; const s:Tsupregset);override;
procedure saveusedotherregisters(list:Taasmoutput; procedure saveusedotherregisters(list:Taasmoutput;
var saved:Tpushedsaved; var saved:Tpushedsavedother;
const s:Tregisterset);override; const s:Tregisterset);override;
procedure restoreusedintregisters(list:Taasmoutput; procedure restoreusedintregisters(list:Taasmoutput;
const saved:Tpushedsavedint);override; const saved:Tpushedsavedint);override;
procedure restoreusedotherregisters(list:Taasmoutput; procedure restoreusedotherregisters(list:Taasmoutput;
const saved:Tpushedsaved);override; const saved:Tpushedsavedother);override;
procedure resetusableregisters;override; procedure resetusableregisters;override;
@ -386,7 +386,7 @@ unit rgcpu;
{$ifdef SUPPORT_MMX} {$ifdef SUPPORT_MMX}
procedure trgcpu.pushusedotherregisters(list:Taasmoutput; procedure trgcpu.pushusedotherregisters(list:Taasmoutput;
var pushed:Tpushedsaved; var pushed:Tpushedsavedother;
const s:Tregisterset); const s:Tregisterset);
var r:Toldregister; var r:Toldregister;
@ -399,7 +399,7 @@ unit rgcpu;
begin begin
pushed[r].pushed:=false; pushed[r].pushed:=false;
{ if the register is used by the calling subroutine } { if the register is used by the calling subroutine }
if not is_reg_var[r] and if not is_reg_var_other[r] and
(r in s) and (r in s) and
{ and is present in use } { and is present in use }
not(r in unusedregsmm) then not(r in unusedregsmm) then
@ -451,7 +451,7 @@ unit rgcpu;
{$ifdef SUPPORT_MMX} {$ifdef SUPPORT_MMX}
procedure trgcpu.popusedotherregisters(list:Taasmoutput; procedure trgcpu.popusedotherregisters(list:Taasmoutput;
const pushed:Tpushedsaved); const pushed:Tpushedsavedother);
var r:Toldregister; var r:Toldregister;
r2,r3:Tregister; r2,r3:Tregister;
@ -495,7 +495,7 @@ unit rgcpu;
end; end;
procedure trgcpu.saveusedotherregisters(list:Taasmoutput;var saved:Tpushedsaved; procedure trgcpu.saveusedotherregisters(list:Taasmoutput;var saved:Tpushedsavedother;
const s:tregisterset); const s:tregisterset);
begin begin
@ -521,7 +521,7 @@ unit rgcpu;
end; end;
procedure trgcpu.restoreusedotherregisters(list:Taasmoutput; procedure trgcpu.restoreusedotherregisters(list:Taasmoutput;
const saved:tpushedsaved); const saved:tpushedsavedother);
begin begin
{$ifdef SUPPORT_MMX} {$ifdef SUPPORT_MMX}
@ -581,7 +581,10 @@ end.
{ {
$Log$ $Log$
Revision 1.21 2003-04-25 08:25:26 daniel Revision 1.22 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.21 2003/04/25 08:25:26 daniel
* Ifdefs around a lot of calls to cleartempgen * Ifdefs around a lot of calls to cleartempgen
* Fixed registers that are allocated but not freed in several nodes * Fixed registers that are allocated but not freed in several nodes
* Tweak to register allocator to cause less spills * Tweak to register allocator to cause less spills

View File

@ -174,8 +174,6 @@ interface
end; end;
tprocinlinenodeclass = class of tprocinlinenode; tprocinlinenodeclass = class of tprocinlinenode;
function initialize_data_node(p:tnode):tnode;
function finalize_data_node(p:tnode):tnode;
function reverseparameters(p: tcallparanode): tcallparanode; function reverseparameters(p: tcallparanode): tcallparanode;
@ -225,36 +223,6 @@ type
end; end;
function initialize_data_node(p:tnode):tnode;
begin
result:=ccallnode.createintern('fpc_initialize',
ccallparanode.create(
caddrnode.create(
crttinode.create(
tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
ccallparanode.create(
p,
nil)));
end;
function finalize_data_node(p:tnode):tnode;
begin
if not assigned(p.resulttype.def) then
resulttypepass(p);
if p.resulttype.def.deftype<>pointerdef then
internalerror(2003051010);
result:=ccallnode.createintern('fpc_finalize',
ccallparanode.create(
caddrnode.create(
crttinode.create(
tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
ccallparanode.create(
p,
nil)));
end;
function gen_high_tree(p:tnode;openstring:boolean):tnode; function gen_high_tree(p:tnode;openstring:boolean):tnode;
var var
temp: tnode; temp: tnode;
@ -2744,7 +2712,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.154 2003-05-14 19:35:50 jonas Revision 1.155 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.154 2003/05/14 19:35:50 jonas
* fixed callparatemp so it works with vs_var, vs_out and formal const * fixed callparatemp so it works with vs_var, vs_out and formal const
parameters parameters

View File

@ -539,7 +539,7 @@ implementation
regs_to_push_int : Tsupregset; regs_to_push_int : Tsupregset;
regs_to_push_other : tregisterset; regs_to_push_other : tregisterset;
unusedstate: pointer; unusedstate: pointer;
pushed : tpushedsaved; pushedother : tpushedsavedother;
pushedint : tpushedsavedint; pushedint : tpushedsavedint;
oldpushedparasize : longint; oldpushedparasize : longint;
{ adress returned from an I/O-error } { adress returned from an I/O-error }
@ -642,7 +642,7 @@ implementation
{$endif cpu64bit} {$endif cpu64bit}
end; end;
rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int); rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
rg.saveusedotherregisters(exprasmlist,pushed,regs_to_push_other); rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
{ give used registers through } { give used registers through }
rg.usedintinproc:=rg.usedintinproc + tprocdef(procdefinition).usedintregisters; rg.usedintinproc:=rg.usedintinproc + tprocdef(procdefinition).usedintregisters;
@ -653,7 +653,7 @@ implementation
regs_to_push_int := all_intregisters; regs_to_push_int := all_intregisters;
regs_to_push_other := all_registers; regs_to_push_other := all_registers;
rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int); rg.saveusedintregisters(exprasmlist,pushedint,regs_to_push_int);
rg.saveusedotherregisters(exprasmlist,pushed,regs_to_push_other); rg.saveusedotherregisters(exprasmlist,pushedother,regs_to_push_other);
rg.usedinproc:=all_registers; rg.usedinproc:=all_registers;
{ no IO check for methods and procedure variables } { no IO check for methods and procedure variables }
iolabel:=nil; iolabel:=nil;
@ -871,7 +871,7 @@ implementation
end; end;
{ restore registers } { restore registers }
rg.restoreusedotherregisters(exprasmlist,pushed); rg.restoreusedotherregisters(exprasmlist,pushedother);
rg.restoreusedintregisters(exprasmlist,pushedint); rg.restoreusedintregisters(exprasmlist,pushedint);
{ Release temps from parameters } { Release temps from parameters }
@ -1128,7 +1128,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.65 2003-05-15 18:58:53 peter Revision 1.66 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.65 2003/05/15 18:58:53 peter
* removed selfpointer_offset, vmtpointer_offset * removed selfpointer_offset, vmtpointer_offset
* tvarsym.adjusted_address * tvarsym.adjusted_address
* address in localsymtable is now in the real direction * address in localsymtable is now in the real direction

View File

@ -180,9 +180,12 @@ implementation
var var
hl,otlabel,oflabel : tasmlabel; hl,otlabel,oflabel : tasmlabel;
org_regvar_loaded, org_regvar_loaded_other,
then_regvar_loaded, then_regvar_loaded_other,
else_regvar_loaded : regvar_booleanarray; else_regvar_loaded_other : regvarother_booleanarray;
org_regvar_loaded_int,
then_regvar_loaded_int,
else_regvar_loaded_int : Tsupregset;
org_list, org_list,
then_list, then_list,
else_list : taasmoutput; else_list : taasmoutput;
@ -210,7 +213,10 @@ implementation
maketojumpbool(exprasmlist,left,lr_dont_load_regvars); maketojumpbool(exprasmlist,left,lr_dont_load_regvars);
if cs_regalloc in aktglobalswitches then if cs_regalloc in aktglobalswitches then
org_regvar_loaded := rg.regvar_loaded; begin
org_regvar_loaded_int := rg.regvar_loaded_int;
org_regvar_loaded_other := rg.regvar_loaded_other;
end;
if assigned(right) then if assigned(right) then
begin begin
@ -225,8 +231,10 @@ implementation
{ loaded regvar state and create new clean ones } { loaded regvar state and create new clean ones }
if cs_regalloc in aktglobalswitches then if cs_regalloc in aktglobalswitches then
begin begin
then_regvar_loaded := rg.regvar_loaded; then_regvar_loaded_int := rg.regvar_loaded_int;
rg.regvar_loaded := org_regvar_loaded; then_regvar_loaded_other := rg.regvar_loaded_other;
rg.regvar_loaded_int := org_regvar_loaded_int;
rg.regvar_loaded_other := org_regvar_loaded_other;
then_list := exprasmlist; then_list := exprasmlist;
exprasmlist := taasmoutput.create; exprasmlist := taasmoutput.create;
end; end;
@ -252,7 +260,8 @@ implementation
{ and loaded regvar state and create a new clean list } { and loaded regvar state and create a new clean list }
if cs_regalloc in aktglobalswitches then if cs_regalloc in aktglobalswitches then
begin begin
else_regvar_loaded := rg.regvar_loaded; else_regvar_loaded_int := rg.regvar_loaded_int;
else_regvar_loaded_other := rg.regvar_loaded_other;
else_list := exprasmlist; else_list := exprasmlist;
exprasmlist := taasmoutput.create; exprasmlist := taasmoutput.create;
end; end;
@ -263,7 +272,8 @@ implementation
begin begin
if cs_regalloc in aktglobalswitches then if cs_regalloc in aktglobalswitches then
begin begin
else_regvar_loaded := rg.regvar_loaded; else_regvar_loaded_int := rg.regvar_loaded_int;
else_regvar_loaded_other := rg.regvar_loaded_other;
else_list := exprasmlist; else_list := exprasmlist;
exprasmlist := taasmoutput.create; exprasmlist := taasmoutput.create;
end; end;
@ -281,16 +291,22 @@ implementation
{ no else block? } { no else block? }
if not assigned(t1) then if not assigned(t1) then
sync_regvars(org_list,then_list,org_regvar_loaded, begin
then_regvar_loaded) sync_regvars_int(org_list,then_list,org_regvar_loaded_int,then_regvar_loaded_int);
sync_regvars_other(org_list,then_list,org_regvar_loaded_other,then_regvar_loaded_other);
end
{ no then block? } { no then block? }
else if not assigned(right) then else if not assigned(right) then
sync_regvars(org_list,else_list,org_regvar_loaded, begin
else_regvar_loaded) sync_regvars_int(org_list,else_list,org_regvar_loaded_int,else_regvar_loaded_int);
sync_regvars_other(org_list,else_list,org_regvar_loaded_other,else_regvar_loaded_other);
end
{ both else and then blocks } { both else and then blocks }
else else
sync_regvars(then_list,else_list,then_regvar_loaded, begin
else_regvar_loaded); sync_regvars_int(then_list,else_list,then_regvar_loaded_int,else_regvar_loaded_int);
sync_regvars_other(then_list,else_list,then_regvar_loaded_other,else_regvar_loaded_other);
end;
{ add all lists together } { add all lists together }
org_list.concatlist(then_list); org_list.concatlist(then_list);
then_list.free; then_list.free;
@ -1538,7 +1554,10 @@ begin
end. end.
{ {
$Log$ $Log$
Revision 1.60 2003-05-13 19:14:41 peter Revision 1.61 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.60 2003/05/13 19:14:41 peter
* failn removed * failn removed
* inherited result code check moven to pexpr * inherited result code check moven to pexpr

View File

@ -51,6 +51,8 @@ interface
function foreachnodestatic(var n: tnode; f: staticforeachnodefunction): boolean; function foreachnodestatic(var n: tnode; f: staticforeachnodefunction): boolean;
function call_fail_node:tnode; function call_fail_node:tnode;
function initialize_data_node(p:tnode):tnode;
function finalize_data_node(p:tnode):tnode;
implementation implementation
@ -58,7 +60,8 @@ implementation
uses uses
verbose, verbose,
symconst,symsym,symtype,symdef,symtable, symconst,symsym,symtype,symdef,symtable,
nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd; nbas,ncon,ncnv,nld,nflw,nset,ncal,nadd,nmem,
pass_1;
function foreachnode(var n: tnode; f: foreachnodefunction): boolean; function foreachnode(var n: tnode; f: foreachnodefunction): boolean;
begin begin
@ -213,12 +216,44 @@ implementation
end; end;
function initialize_data_node(p:tnode):tnode;
begin
if not assigned(p.resulttype.def) then
resulttypepass(p);
result:=ccallnode.createintern('fpc_initialize',
ccallparanode.create(
caddrnode.create(
crttinode.create(
tstoreddef(p.resulttype.def),initrtti)),
ccallparanode.create(
caddrnode.create(p),
nil)));
end;
function finalize_data_node(p:tnode):tnode;
begin
if not assigned(p.resulttype.def) then
resulttypepass(p);
result:=ccallnode.createintern('fpc_finalize',
ccallparanode.create(
caddrnode.create(
crttinode.create(
tstoreddef(p.resulttype.def),initrtti)),
ccallparanode.create(
caddrnode.create(p),
nil)));
end;
end. end.
{ {
$Log$ $Log$
Revision 1.3 2003-05-13 20:54:06 peter Revision 1.4 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.3 2003/05/13 20:54:06 peter
* fail checks vmt value before calling dispose * fail checks vmt value before calling dispose
Revision 1.2 2003/05/13 19:14:41 peter Revision 1.2 2003/05/13 19:14:41 peter

View File

@ -55,7 +55,7 @@ implementation
symconst,symdef,symsym,symtable,defutil, symconst,symdef,symsym,symtable,defutil,
{ pass 1 } { pass 1 }
pass_1,htypechk, pass_1,htypechk,
nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas, nmat,nadd,ncal,nmem,nset,ncnv,ninl,ncon,nld,nflw,nbas,nutils,
{ parser } { parser }
scanner, scanner,
pbase,pexpr, pbase,pexpr,
@ -243,13 +243,7 @@ implementation
{ create call to fpc_initialize } { create call to fpc_initialize }
if tpointerdef(p.resulttype.def).pointertype.def.needs_inittable then if tpointerdef(p.resulttype.def).pointertype.def.needs_inittable then
begin addstatement(newstatement,initialize_data_node(ctemprefnode.create(temp)));
para := ccallparanode.create(caddrnode.create(crttinode.create(
tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
ccallparanode.create(ctemprefnode.create
(temp),nil));
addstatement(newstatement,ccallnode.createintern('fpc_initialize',para));
end;
{ copy the temp to the destination } { copy the temp to the destination }
addstatement(newstatement,cassignmentnode.create( addstatement(newstatement,cassignmentnode.create(
@ -263,13 +257,7 @@ implementation
begin begin
{ create call to fpc_finalize } { create call to fpc_finalize }
if tpointerdef(p.resulttype.def).pointertype.def.needs_inittable then if tpointerdef(p.resulttype.def).pointertype.def.needs_inittable then
begin addstatement(newstatement,finalize_data_node(cderefnode.create(p.getcopy)));
{ we need to use a copy of p here }
para := ccallparanode.create(caddrnode.create(crttinode.create
(tstoreddef(tpointerdef(p.resulttype.def).pointertype.def),initrtti)),
ccallparanode.create(p.getcopy,nil));
addstatement(newstatement,ccallnode.createintern('fpc_finalize',para));
end;
{ create call to fpc_freemem } { create call to fpc_freemem }
para := ccallparanode.create(p,nil); para := ccallparanode.create(p,nil);
@ -578,12 +566,7 @@ implementation
end end
else else
begin begin
{ create call to fpc_finalize } newblock:=finalize_data_node(ppn.left);
npara:=ccallparanode.create(caddrnode.create
(crttinode.create(tstoreddef(ppn.left.resulttype.def),initrtti)),
ccallparanode.create(caddrnode.create
(ppn.left),nil));
newblock:=ccallnode.createintern('fpc_finalize',npara);
ppn.left:=nil; ppn.left:=nil;
end; end;
paras.free; paras.free;
@ -699,7 +682,10 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.13 2003-05-09 17:47:03 peter Revision 1.14 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.13 2003/05/09 17:47:03 peter
* self moved to hidden parameter * self moved to hidden parameter
* removed hdisposen,hnewn,selfn * removed hdisposen,hnewn,selfn

View File

@ -396,6 +396,9 @@ implementation
else else
if is_object(current_procdef._class) then if is_object(current_procdef._class) then
begin begin
{ finalize object data }
if current_procdef._class.needs_inittable then
addstatement(newstatement,finalize_data_node(load_self_node));
{ parameter 3 : vmt_offset } { parameter 3 : vmt_offset }
{ parameter 2 : pointer to vmt } { parameter 2 : pointer to vmt }
{ parameter 1 : self pointer } { parameter 1 : self pointer }
@ -451,7 +454,7 @@ implementation
if (not is_void(current_procdef.rettype.def)) and if (not is_void(current_procdef.rettype.def)) and
(current_procdef.rettype.def.needs_inittable) and (current_procdef.rettype.def.needs_inittable) and
(not is_class(current_procdef.rettype.def)) then (not is_class(current_procdef.rettype.def)) then
finalize_data_node(caddrnode.create(load_result_node)); finalize_data_node(load_result_node);
end; end;
end; end;
@ -1127,7 +1130,10 @@ implementation
end. end.
{ {
$Log$ $Log$
Revision 1.112 2003-05-13 21:26:38 peter Revision 1.113 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.112 2003/05/13 21:26:38 peter
* only call destructor in except block when there is a destructor * only call destructor in except block when there is a destructor
available available

View File

@ -35,14 +35,15 @@ interface
procedure assign_regvars(p: tnode); procedure assign_regvars(p: tnode);
procedure load_regvars(asml: TAAsmoutput; p: tnode); procedure load_regvars(asml: TAAsmoutput; p: tnode);
procedure cleanup_regvars(asml: TAAsmoutput); procedure cleanup_regvars(asml: TAAsmoutput);
procedure store_regvar_int(asml:Taasmoutput;reg:Tsuperregister);
procedure store_regvar(asml: TAAsmoutput; reg: tregister); procedure store_regvar(asml: TAAsmoutput; reg: tregister);
procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym); procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister); procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
procedure load_all_regvars(asml: TAAsmoutput); procedure load_all_regvars(asml: TAAsmoutput);
procedure sync_regvars(list1, list2: taasmoutput; const regvarsloaded1, procedure sync_regvars_other(list1, list2: taasmoutput; const regvarsloaded1,
regvarsloaded2: regvar_booleanarray); regvarsloaded2: regvarother_booleanarray);
procedure sync_regvars_int(list1, list2: taasmoutput; const regvarsloaded1,
regvarsloaded2: Tsupregset);
implementation implementation
@ -141,6 +142,7 @@ implementation
i: longint; i: longint;
parasym : boolean; parasym : boolean;
r : Tregister; r : Tregister;
siz : tcgsize;
begin begin
{ max. optimizations } { max. optimizations }
{ only if no asm is used } { only if no asm is used }
@ -169,48 +171,34 @@ implementation
for i:=1 to maxvarregs-p.registers32 do for i:=1 to maxvarregs-p.registers32 do
begin begin
if assigned(regvarinfo^.regvars[i]) and if assigned(regvarinfo^.regvars[i]) and
(rg.reg_pushes[varregs[i]] < regvarinfo^.regvars[i].refs) then (rg.reg_pushes_int[varregs[i]] < regvarinfo^.regvars[i].refs) then
begin begin
{ register is no longer available for } { register is no longer available for }
{ expressions } { expressions }
{ search the register which is the most } { search the register which is the most }
{ unused } { unused }
r.enum:=varregs[i]; rg.makeregvarint(varregs[i]);
if r.enum=R_INTREGISTER then
rg.makeregvarint(r.number)
else
rg.makeregvarother(r);
{ possibly no 32 bit register are needed }
{ call by reference/const ? } { call by reference/const ? }
if (regvarinfo^.regvars[i].varspez in [vs_var,vs_out]) or if (regvarinfo^.regvars[i].varspez in [vs_var,vs_out]) or
((regvarinfo^.regvars[i].varspez=vs_const) and ((regvarinfo^.regvars[i].varspez=vs_const) and
paramanager.push_addr_param(regvarinfo^.regvars[i].vartype.def,current_procdef.proccalloption)) then paramanager.push_addr_param(regvarinfo^.regvars[i].vartype.def,current_procdef.proccalloption)) then
begin siz:=OS_32
r.enum:=varregs[i];
regvarinfo^.regvars[i].reg:=r;
end
else else
if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
(regvarinfo^.regvars[i].vartype.def.size=1) then (regvarinfo^.regvars[i].vartype.def.size=1) then
begin siz:=OS_8
r.enum:=varregs[i];
regvarinfo^.regvars[i].reg:=rg.makeregsize(r,OS_8);
end
else else
if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
(regvarinfo^.regvars[i].vartype.def.size=2) then (regvarinfo^.regvars[i].vartype.def.size=2) then
begin siz:=OS_16
r.enum:=varregs[i];
regvarinfo^.regvars[i].reg:=rg.makeregsize(r,OS_16);
end
else else
begin siz:=OS_32;
r.enum:=varregs[i];
regvarinfo^.regvars[i].reg:=r; regvarinfo^.regvars[i].reg.enum:=R_INTREGISTER;
end; regvarinfo^.regvars[i].reg.number:=(varregs[i] shl 8) or cgsize2subreg(siz);
{ procedure uses this register } { procedure uses this register }
include(rg.usedinproc,varregs[i]); include(rg.usedintinproc,varregs[i]);
end end
else else
begin begin
@ -274,66 +262,107 @@ implementation
end; end;
procedure store_regvar_int(asml:Taasmoutput;reg:Tsuperregister);
begin
internalerror(200301104);
end;
procedure store_regvar(asml: TAAsmoutput; reg: tregister); procedure store_regvar(asml: TAAsmoutput; reg: tregister);
var var
i: longint; i: longint;
r : tregister;
hr: treference; hr: treference;
regvarinfo: pregvarinfo; regvarinfo: pregvarinfo;
vsym: tvarsym; vsym: tvarsym;
begin begin
if reg.enum>lastreg then
internalerror(200301081);
regvarinfo := pregvarinfo(current_procdef.regvarinfo); regvarinfo := pregvarinfo(current_procdef.regvarinfo);
if not assigned(regvarinfo) then if not assigned(regvarinfo) then
exit; exit;
for i := 1 to maxvarregs do if reg.enum=R_INTREGISTER then
if assigned(regvarinfo^.regvars[i]) and begin
(rg.makeregsize(regvarinfo^.regvars[i].reg,OS_INT).enum = reg.enum) then for i := 1 to maxvarregs do
begin if assigned(regvarinfo^.regvars[i]) and
if rg.regvar_loaded[rg.makeregsize(reg,OS_INT).enum] then (regvarinfo^.regvars[i].reg.number shr 8 = reg.number shr 8) then
begin begin
vsym := tvarsym(regvarinfo^.regvars[i]); if (reg.number shr 8) in rg.regvar_loaded_int then
{ we only have to store the regvar back to memory if it's }
{ possible that it's been modified (JM) }
if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
begin begin
reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address); vsym := tvarsym(regvarinfo^.regvars[i]);
cg.a_load_reg_ref(asml,def_cgsize(vsym.vartype.def),vsym.reg,hr); { we only have to store the regvar back to memory if it's }
{ possible that it's been modified (JM) }
if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
begin
reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
cg.a_load_reg_ref(asml,def_cgsize(vsym.vartype.def),vsym.reg,hr);
end;
asml.concat(tai_regalloc.dealloc(vsym.reg));
exclude(rg.regvar_loaded_int,reg.number shr 8);
end; end;
asml.concat(tai_regalloc.dealloc(rg.makeregsize(reg,OS_INT))); break;
rg.regvar_loaded[rg.makeregsize(reg,OS_INT).enum] := false;
end; end;
break; end
end; else
begin
for i := 1 to maxvarregs do
if assigned(regvarinfo^.regvars[i]) then
begin
r:=rg.makeregsize(regvarinfo^.regvars[i].reg,OS_INT);
if (r.enum = reg.enum) then
begin
if rg.regvar_loaded_other[r.enum] then
begin
vsym := tvarsym(regvarinfo^.regvars[i]);
{ we only have to store the regvar back to memory if it's }
{ possible that it's been modified (JM) }
if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
begin
reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
cg.a_load_reg_ref(asml,def_cgsize(vsym.vartype.def),vsym.reg,hr);
end;
asml.concat(tai_regalloc.dealloc(vsym.reg));
rg.regvar_loaded_other[r.enum] := false;
end;
break;
end;
end;
end;
end; end;
procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym); procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
var var
hr: treference; hr: treference;
opsize: tcgsize; opsize: tcgsize;
r,
reg : tregister; reg : tregister;
begin begin
reg:=rg.makeregsize(vsym.reg,OS_INT); reg:=vsym.reg;
if reg.enum>lastreg then if reg.enum=R_INTREGISTER then
internalerror(200301081);
if not rg.regvar_loaded[reg.enum] then
begin begin
asml.concat(tai_regalloc.alloc(reg)); if not((reg.number shr 8) in rg.regvar_loaded_int) then
reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address); begin
if (vsym.varspez in [vs_var,vs_out]) or asml.concat(tai_regalloc.alloc(reg));
((vsym.varspez=vs_const) and reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
paramanager.push_addr_param(vsym.vartype.def,current_procdef.proccalloption)) then if (vsym.varspez in [vs_var,vs_out]) or
opsize := OS_ADDR ((vsym.varspez=vs_const) and
else paramanager.push_addr_param(vsym.vartype.def,current_procdef.proccalloption)) then
opsize := def_cgsize(vsym.vartype.def); opsize := OS_ADDR
cg.a_load_ref_reg(asml,opsize,hr,reg); else
rg.regvar_loaded[reg.enum] := true; opsize := def_cgsize(vsym.vartype.def);
cg.a_load_ref_reg(asml,opsize,hr,reg);
include(rg.regvar_loaded_int,reg.number shr 8);
end;
end
else
begin
r:=rg.makeregsize(reg,OS_INT);
if not rg.regvar_loaded_other[r.enum] then
begin
asml.concat(tai_regalloc.alloc(reg));
reference_reset_base(hr,current_procinfo.framepointer,vsym.adjusted_address);
if (vsym.varspez in [vs_var,vs_out]) or
((vsym.varspez=vs_const) and
paramanager.push_addr_param(vsym.vartype.def,current_procdef.proccalloption)) then
opsize := OS_ADDR
else
opsize := def_cgsize(vsym.vartype.def);
cg.a_load_ref_reg(asml,opsize,hr,reg);
rg.regvar_loaded_other[r.enum] := true;
end;
end; end;
end; end;
@ -346,13 +375,23 @@ implementation
regvarinfo := pregvarinfo(current_procdef.regvarinfo); regvarinfo := pregvarinfo(current_procdef.regvarinfo);
if not assigned(regvarinfo) then if not assigned(regvarinfo) then
exit; exit;
reg_spare := rg.makeregsize(reg,OS_INT); if reg.enum=R_INTREGISTER then
if reg_spare.enum>lastreg then begin
internalerror(2003010801); for i := 1 to maxvarregs do
for i := 1 to maxvarregs do if assigned(regvarinfo^.regvars[i]) and
if assigned(regvarinfo^.regvars[i]) and (regvarinfo^.regvars[i].reg.number shr 8 = reg.number shr 8) then
(rg.makeregsize(regvarinfo^.regvars[i].reg,OS_INT).enum = reg_spare.enum) then load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
load_regvar(asml,tvarsym(regvarinfo^.regvars[i])) end
else
begin
reg_spare := rg.makeregsize(reg,OS_INT);
if reg_spare.enum>lastreg then
internalerror(2003010801);
for i := 1 to maxvarregs do
if assigned(regvarinfo^.regvars[i]) and
(rg.makeregsize(regvarinfo^.regvars[i].reg,OS_INT).enum = reg_spare.enum) then
load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
end;
end; end;
procedure load_all_regvars(asml: TAAsmoutput); procedure load_all_regvars(asml: TAAsmoutput);
@ -364,8 +403,7 @@ implementation
if not assigned(regvarinfo) then if not assigned(regvarinfo) then
exit; exit;
for i := 1 to maxvarregs do for i := 1 to maxvarregs do
if assigned(regvarinfo^.regvars[i]) {and if assigned(regvarinfo^.regvars[i]) then
(makereg32(regvarinfo^.regvars[i].reg) in [R_EAX,R_EBX,R_ECX,R_EDX])} then
load_regvar(asml,tvarsym(regvarinfo^.regvars[i])) load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
end; end;
@ -388,12 +426,13 @@ implementation
begin begin
if assigned(regvarinfo^.regvars[i]) then if assigned(regvarinfo^.regvars[i]) then
begin begin
r:=regvarinfo^.regvars[i].reg;
convert_register_to_enum(r);
if cs_asm_source in aktglobalswitches then if cs_asm_source in aktglobalswitches then
asml.insert(tai_comment.Create(strpnew(regvarinfo^.regvars[i].name+ asml.insert(tai_comment.Create(strpnew(regvarinfo^.regvars[i].name+
' with weight '+tostr(regvarinfo^.regvars[i].refs)+' assigned to register '+ ' with weight '+tostr(regvarinfo^.regvars[i].refs)+' assigned to register '+
std_reg2str[regvarinfo^.regvars[i].reg.enum]))); std_reg2str[r.enum])));
if (status.verbosity and v_debug)=v_debug then Message3(cg_d_register_weight,std_reg2str[r.enum],
Message3(cg_d_register_weight,std_reg2str[regvarinfo^.regvars[i].reg.enum],
tostr(regvarinfo^.regvars[i].refs),regvarinfo^.regvars[i].name); tostr(regvarinfo^.regvars[i].refs),regvarinfo^.regvars[i].name);
end; end;
end; end;
@ -434,14 +473,14 @@ implementation
end; end;
procedure sync_regvars(list1, list2: taasmoutput; const regvarsloaded1, procedure sync_regvars_other(list1, list2: taasmoutput; const regvarsloaded1,
regvarsloaded2: regvar_booleanarray); regvarsloaded2: regvarother_booleanarray);
var var
counter: tregister; counter: tregister;
begin begin
for counter.enum := low(rg.regvar_loaded) to high(rg.regvar_loaded) do for counter.enum := low(rg.regvar_loaded_other) to high(rg.regvar_loaded_other) do
begin begin
rg.regvar_loaded[counter.enum] := regvarsloaded1[counter.enum] and rg.regvar_loaded_other[counter.enum] := regvarsloaded1[counter.enum] and
regvarsloaded2[counter.enum]; regvarsloaded2[counter.enum];
if regvarsloaded1[counter.enum] xor regvarsloaded2[counter.enum] then if regvarsloaded1[counter.enum] xor regvarsloaded2[counter.enum] then
if regvarsloaded1[counter.enum] then if regvarsloaded1[counter.enum] then
@ -452,6 +491,27 @@ implementation
end; end;
procedure sync_regvars_int(list1, list2: taasmoutput; const regvarsloaded1,
regvarsloaded2: Tsupregset);
var
i : longint;
r : tregister;
begin
for i:=1 to maxvarregs do
begin
r.enum:=R_INTREGISTER;
r.number:=varregs[i] shl 8;
if (varregs[i] in regvarsloaded1) and
not(varregs[i] in regvarsloaded2) then
load_regvar_reg(list2,r)
else
if (varregs[i] in regvarsloaded2) and
not(varregs[i] in regvarsloaded1) then
load_regvar_reg(list1,r);
end;
end;
procedure cleanup_regvars(asml: TAAsmoutput); procedure cleanup_regvars(asml: TAAsmoutput);
var var
i: longint; i: longint;
@ -476,11 +536,22 @@ implementation
begin begin
if assigned(regvars[i]) then if assigned(regvars[i]) then
begin begin
reg:=rg.makeregsize(regvars[i].reg,OS_INT); reg:=regvars[i].reg;
if reg.enum>lastreg then if reg.enum=R_INTREGISTER then
internalerror(200201081); begin
if (rg.regvar_loaded[reg.enum]) then if (reg.number shr 8 in rg.regvar_loaded_int) then
asml.concat(tai_regalloc.dealloc(reg)); asml.concat(tai_regalloc.dealloc(reg));
end
else
begin
reg.number:=(r.number and not $ff) or cgsize2subreg(OS_INT);
r:=reg;
convert_register_to_enum(r);
if r.enum>lastreg then
internalerror(200201081);
if (rg.regvar_loaded_other[r.enum]) then
asml.concat(tai_regalloc.dealloc(reg));
end;
end; end;
end; end;
end; end;
@ -490,7 +561,10 @@ end.
{ {
$Log$ $Log$
Revision 1.49 2003-05-15 18:58:53 peter Revision 1.50 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.49 2003/05/15 18:58:53 peter
* removed selfpointer_offset, vmtpointer_offset * removed selfpointer_offset, vmtpointer_offset
* tvarsym.adjusted_address * tvarsym.adjusted_address
* address in localsymtable is now in the real direction * address in localsymtable is now in the real direction

View File

@ -89,10 +89,10 @@ unit rgobj;
type type
regvar_longintarray = array[firstreg..lastreg] of longint; regvarother_longintarray = array[firstreg..lastreg] of longint;
regvarother_booleanarray = array[firstreg..lastreg] of boolean;
regvarint_longintarray = array[first_supreg..last_supreg] of longint; regvarint_longintarray = array[first_supreg..last_supreg] of longint;
regvar_booleanarray = array[firstreg..lastreg] of boolean; regvarint_ptreearray = array[first_supreg..last_supreg] of tnode;
regvar_ptreearray = array[firstreg..lastreg] of tnode;
tpushedsavedloc = record tpushedsavedloc = record
case byte of case byte of
@ -100,7 +100,7 @@ unit rgobj;
1: (ofs: longint); 1: (ofs: longint);
end; end;
tpushedsaved = array[firstreg..lastreg] of tpushedsavedloc; tpushedsavedother = array[firstreg..lastreg] of tpushedsavedloc;
Tpushedsavedint = array[first_supreg..last_supreg] of Tpushedsavedloc; Tpushedsavedint = array[first_supreg..last_supreg] of Tpushedsavedloc;
Tinterferencebitmap=array[Tsuperregister] of set of Tsuperregister; Tinterferencebitmap=array[Tsuperregister] of set of Tsuperregister;
@ -173,11 +173,11 @@ unit rgobj;
usedintinproc, usedintinproc,
usedaddrinproc:Tsupregset; usedaddrinproc:Tsupregset;
reg_pushes : regvar_longintarray; reg_pushes_other : regvarother_longintarray;
reg_pushes_int : regvarint_longintarray; reg_pushes_int : regvarint_longintarray;
is_reg_var : regvar_booleanarray; is_reg_var_other : regvarother_booleanarray;
is_reg_var_int:Tsupregset; is_reg_var_int:Tsupregset;
regvar_loaded: regvar_booleanarray; regvar_loaded_other: regvarother_booleanarray;
regvar_loaded_int: Tsupregset; regvar_loaded_int: Tsupregset;
{$ifdef newra} {$ifdef newra}
colour:array[Tsuperregister] of Tsuperregister; colour:array[Tsuperregister] of Tsuperregister;
@ -297,7 +297,7 @@ unit rgobj;
var saved:Tpushedsavedint; var saved:Tpushedsavedint;
const s:Tsupregset);virtual; const s:Tsupregset);virtual;
procedure saveusedotherregisters(list:Taasmoutput; procedure saveusedotherregisters(list:Taasmoutput;
var saved:Tpushedsaved; var saved:Tpushedsavedother;
const s:Tregisterset);virtual; const s:Tregisterset);virtual;
{# Restores the registers which were saved with a call {# Restores the registers which were saved with a call
to @var(saveusedregisters). to @var(saveusedregisters).
@ -308,7 +308,7 @@ unit rgobj;
procedure restoreusedintregisters(list:Taasmoutput; procedure restoreusedintregisters(list:Taasmoutput;
const saved:Tpushedsavedint);virtual; const saved:Tpushedsavedint);virtual;
procedure restoreusedotherregisters(list:Taasmoutput; procedure restoreusedotherregisters(list:Taasmoutput;
const saved:Tpushedsaved);virtual; const saved:Tpushedsavedother);virtual;
{ used when deciding which registers to use for regvars } { used when deciding which registers to use for regvars }
procedure incrementintregisterpushed(const s:Tsupregset); procedure incrementintregisterpushed(const s:Tsupregset);
@ -316,7 +316,7 @@ unit rgobj;
procedure clearregistercount; procedure clearregistercount;
procedure resetusableregisters;virtual; procedure resetusableregisters;virtual;
procedure makeregvarint(reg:Tnewregister); procedure makeregvarint(reg:Tsuperregister);
procedure makeregvarother(reg:Tregister); procedure makeregvarother(reg:Tregister);
procedure saveStateForInline(var state: pointer);virtual; procedure saveStateForInline(var state: pointer);virtual;
@ -443,10 +443,11 @@ unit rgobj;
{ contains the registers which are really used by the proc itself } { contains the registers which are really used by the proc itself }
usedbyproc, usedbyproc,
usedinproc : tregisterset; usedinproc : tregisterset;
reg_pushes : regvar_longintarray; reg_pushes_other : regvarother_longintarray;
is_reg_var : regvar_booleanarray; reg_pushes_int : regvarint_longintarray;
is_reg_var_other : regvarother_booleanarray;
is_reg_var_int : Tsupregset; is_reg_var_int : Tsupregset;
regvar_loaded: regvar_booleanarray; regvar_loaded_other: regvarother_booleanarray;
regvar_loaded_int: Tsupregset; regvar_loaded_int: Tsupregset;
{$ifdef TEMPREGDEBUG} {$ifdef TEMPREGDEBUG}
reg_user : regvar_ptreearray; reg_user : regvar_ptreearray;
@ -787,6 +788,7 @@ unit rgobj;
function trgobj.isaddressregister(reg: tregister): boolean; function trgobj.isaddressregister(reg: tregister): boolean;
begin begin
if reg.number<>0 then; { remove warning }
result := true; result := true;
end; end;
@ -860,14 +862,18 @@ unit rgobj;
procedure trgobj.saveintregvars(list:Taasmoutput;const s:Tsupregset); procedure trgobj.saveintregvars(list:Taasmoutput;const s:Tsupregset);
var r:Tsuperregister; var r:Tsuperregister;
hr: tregister;
begin begin
if not(cs_regalloc in aktglobalswitches) then if not(cs_regalloc in aktglobalswitches) then
exit; exit;
for r:=firstsaveintreg to lastsaveintreg do for r:=firstsaveintreg to lastsaveintreg do
if (r in is_reg_var_int) and if (r in is_reg_var_int) and
(r in s) then (r in s) then
store_regvar_int(list,r); begin
hr.number:=r shl 8;
hr.enum:=R_INTREGISTER;
store_regvar(list,hr);
end;
end; end;
procedure trgobj.saveotherregvars(list: taasmoutput; const s: tregisterset); procedure trgobj.saveotherregvars(list: taasmoutput; const s: tregisterset);
@ -878,12 +884,12 @@ unit rgobj;
exit; exit;
if firstsavefpureg <> R_NO then if firstsavefpureg <> R_NO then
for r.enum := firstsavefpureg to lastsavefpureg do for r.enum := firstsavefpureg to lastsavefpureg do
if is_reg_var[r.enum] and if is_reg_var_other[r.enum] and
(r.enum in s) then (r.enum in s) then
store_regvar(list,r); store_regvar(list,r);
if firstsavemmreg <> R_NO then if firstsavemmreg <> R_NO then
for r.enum := firstsavemmreg to lastsavemmreg do for r.enum := firstsavemmreg to lastsavemmreg do
if is_reg_var[r.enum] and if is_reg_var_other[r.enum] and
(r.enum in s) then (r.enum in s) then
store_regvar(list,r); store_regvar(list,r);
end; end;
@ -928,7 +934,7 @@ unit rgobj;
end; end;
procedure trgobj.saveusedotherregisters(list: taasmoutput; procedure trgobj.saveusedotherregisters(list: taasmoutput;
var saved : tpushedsaved; const s: tregisterset); var saved : tpushedsavedother; const s: tregisterset);
var var
r : tregister; r : tregister;
@ -945,7 +951,7 @@ unit rgobj;
saved[r.enum].ofs:=reg_not_saved; saved[r.enum].ofs:=reg_not_saved;
{ if the register is used by the calling subroutine and if } { if the register is used by the calling subroutine and if }
{ it's not a regvar (those are handled separately) } { it's not a regvar (those are handled separately) }
if not is_reg_var[r.enum] and if not is_reg_var_other[r.enum] and
(r.enum in s) and (r.enum in s) and
{ and is present in use } { and is present in use }
not(r.enum in unusedregsfpu) then not(r.enum in unusedregsfpu) then
@ -967,7 +973,7 @@ unit rgobj;
saved[r.enum].ofs:=reg_not_saved; saved[r.enum].ofs:=reg_not_saved;
{ if the register is in use and if it's not a regvar (those } { if the register is in use and if it's not a regvar (those }
{ are handled separately), save it } { are handled separately), save it }
if not is_reg_var[r.enum] and if not is_reg_var_other[r.enum] and
(r.enum in s) and (r.enum in s) and
{ and is present in use } { and is present in use }
not(r.enum in unusedregsmm) then not(r.enum in unusedregsmm) then
@ -1027,7 +1033,7 @@ unit rgobj;
end; end;
procedure trgobj.restoreusedotherregisters(list : taasmoutput; procedure trgobj.restoreusedotherregisters(list : taasmoutput;
const saved : tpushedsaved); const saved : tpushedsavedother);
var var
r,r2 : tregister; r,r2 : tregister;
@ -1109,13 +1115,13 @@ unit rgobj;
for regi:=firstsavefpureg to lastsavefpureg do for regi:=firstsavefpureg to lastsavefpureg do
begin begin
if (regi in s) then if (regi in s) then
inc(reg_pushes[regi],t_times*2); inc(reg_pushes_other[regi],t_times*2);
end; end;
if firstsavemmreg <> R_NO then if firstsavemmreg <> R_NO then
for regi:=firstsavemmreg to lastsavemmreg do for regi:=firstsavemmreg to lastsavemmreg do
begin begin
if (regi in s) then if (regi in s) then
inc(reg_pushes[regi],t_times*2); inc(reg_pushes_other[regi],t_times*2);
end; end;
end; end;
@ -1123,10 +1129,11 @@ unit rgobj;
procedure trgobj.clearregistercount; procedure trgobj.clearregistercount;
begin begin
fillchar(reg_pushes,sizeof(reg_pushes),0); fillchar(reg_pushes_int,sizeof(reg_pushes_int),0);
fillchar(is_reg_var,sizeof(is_reg_var),false); fillchar(reg_pushes_other,sizeof(reg_pushes_other),0);
fillchar(is_reg_var_other,sizeof(is_reg_var_other),false);
is_reg_var_int:=[]; is_reg_var_int:=[];
fillchar(regvar_loaded,sizeof(regvar_loaded),false); fillchar(regvar_loaded_other,sizeof(regvar_loaded_other),false);
regvar_loaded_int:=[]; regvar_loaded_int:=[];
end; end;
@ -1145,19 +1152,15 @@ unit rgobj;
end; end;
procedure trgobj.makeregvarint(reg:Tnewregister); procedure trgobj.makeregvarint(reg:Tsuperregister);
var supreg:Tsuperregister;
begin begin
supreg:=reg shr 8;
dec(countusableregsint); dec(countusableregsint);
{$ifndef newra} {$ifndef newra}
dec(countunusedregsint); dec(countunusedregsint);
{$endif} {$endif}
exclude(usableregsint,reg); exclude(usableregsint,reg shl 8);
exclude(unusedregsint,reg); exclude(unusedregsint,reg shl 8);
include(is_reg_var_int,supreg); include(is_reg_var_int,reg);
end; end;
procedure trgobj.makeregvarother(reg: tregister); procedure trgobj.makeregvarother(reg: tregister);
@ -1180,7 +1183,7 @@ unit rgobj;
exclude(usableregsmm,reg.enum); exclude(usableregsmm,reg.enum);
exclude(unusedregsmm,reg.enum); exclude(unusedregsmm,reg.enum);
end; end;
is_reg_var[reg.enum]:=true; is_reg_var_other[reg.enum]:=true;
end; end;
@ -1218,11 +1221,12 @@ unit rgobj;
psavedstate(state)^.countusableregsmm := countusableregsmm; psavedstate(state)^.countusableregsmm := countusableregsmm;
psavedstate(state)^.usedinproc := usedinproc; psavedstate(state)^.usedinproc := usedinproc;
psavedstate(state)^.usedbyproc := usedbyproc; psavedstate(state)^.usedbyproc := usedbyproc;
psavedstate(state)^.reg_pushes := reg_pushes; psavedstate(state)^.reg_pushes_int := reg_pushes_int;
psavedstate(state)^.is_reg_var := is_reg_var; psavedstate(state)^.reg_pushes_other := reg_pushes_other;
psavedstate(state)^.is_reg_var_int := is_reg_var_int; psavedstate(state)^.is_reg_var_int := is_reg_var_int;
psavedstate(state)^.regvar_loaded := regvar_loaded; psavedstate(state)^.is_reg_var_other := is_reg_var_other;
psavedstate(state)^.regvar_loaded_int := regvar_loaded_int; psavedstate(state)^.regvar_loaded_int := regvar_loaded_int;
psavedstate(state)^.regvar_loaded_other := regvar_loaded_other;
{$ifdef TEMPREGDEBUG} {$ifdef TEMPREGDEBUG}
psavedstate(state)^.reg_user := reg_user; psavedstate(state)^.reg_user := reg_user;
psavedstate(state)^.reg_releaser := reg_releaser; psavedstate(state)^.reg_releaser := reg_releaser;
@ -1248,10 +1252,11 @@ unit rgobj;
countusableregsmm := psavedstate(state)^.countusableregsmm; countusableregsmm := psavedstate(state)^.countusableregsmm;
usedinproc := psavedstate(state)^.usedinproc; usedinproc := psavedstate(state)^.usedinproc;
usedbyproc := psavedstate(state)^.usedbyproc; usedbyproc := psavedstate(state)^.usedbyproc;
reg_pushes := psavedstate(state)^.reg_pushes; reg_pushes_int := psavedstate(state)^.reg_pushes_int;
is_reg_var := psavedstate(state)^.is_reg_var; reg_pushes_other := psavedstate(state)^.reg_pushes_other;
is_reg_var_int := psavedstate(state)^.is_reg_var_int; is_reg_var_int := psavedstate(state)^.is_reg_var_int;
regvar_loaded := psavedstate(state)^.regvar_loaded; is_reg_var_other := psavedstate(state)^.is_reg_var_other;
regvar_loaded_other := psavedstate(state)^.regvar_loaded_other;
regvar_loaded_int := psavedstate(state)^.regvar_loaded_int; regvar_loaded_int := psavedstate(state)^.regvar_loaded_int;
{$ifdef TEMPREGDEBUG} {$ifdef TEMPREGDEBUG}
reg_user := psavedstate(state)^.reg_user; reg_user := psavedstate(state)^.reg_user;
@ -2022,7 +2027,10 @@ end.
{ {
$Log$ $Log$
Revision 1.42 2003-04-26 20:03:49 daniel Revision 1.43 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.42 2003/04/26 20:03:49 daniel
* Bug fix in simplify * Bug fix in simplify
Revision 1.41 2003/04/25 20:59:35 peter Revision 1.41 2003/04/25 20:59:35 peter

View File

@ -1697,6 +1697,8 @@ unit cgx86;
r.number:=NR_EDX; r.number:=NR_EDX;
list.concat(Taicpu.Op_reg(A_POP,S_L,r)); list.concat(Taicpu.Op_reg(A_POP,S_L,r));
end; end;
r.number:=NR_ESI;
list.concat(Taicpu.Op_reg(A_POP,S_L,r));
r.number:=NR_EDI; r.number:=NR_EDI;
list.concat(Taicpu.Op_reg(A_POP,S_L,r)); list.concat(Taicpu.Op_reg(A_POP,S_L,r));
{ .... also the segment registers } { .... also the segment registers }
@ -1939,7 +1941,10 @@ unit cgx86;
end. end.
{ {
$Log$ $Log$
Revision 1.45 2003-05-15 18:58:54 peter Revision 1.46 2003-05-16 14:33:31 peter
* regvar fixes
Revision 1.45 2003/05/15 18:58:54 peter
* removed selfpointer_offset, vmtpointer_offset * removed selfpointer_offset, vmtpointer_offset
* tvarsym.adjusted_address * tvarsym.adjusted_address
* address in localsymtable is now in the real direction * address in localsymtable is now in the real direction