* constant regvars (addresses of var/out para's and const para's) aren't

saved to memory anymore when their register will be destroyed
  * unit has been made mostly processor independent
This commit is contained in:
Jonas Maebe 2001-11-05 16:49:32 +00:00
parent 9b628f6409
commit 4d0eae9a7c

View File

@ -35,12 +35,10 @@ 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);
{$ifdef i386}
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);
{$endif i386}
implementation implementation
@ -48,7 +46,7 @@ implementation
globtype,systems,comphook, globtype,systems,comphook,
cutils,cclasses,verbose,globals, cutils,cclasses,verbose,globals,
symconst,symbase,symtype,symdef,types, symconst,symbase,symtype,symdef,types,
cgbase,cpuasm,tgcpu; cgbase,cpuasm,tgcpu,cgobj,cgcpu,cga;
var var
parasym : boolean; parasym : boolean;
@ -130,30 +128,12 @@ implementation
end; end;
end; end;
{$ifdef i386}
function reg32(reg: tregister): tregister;
begin
case regsize(reg) of
S_B: reg32 := reg8toreg32(reg);
S_W: reg32 := reg16toreg32(reg);
S_L: reg32 := reg;
end;
end;
{$else i386}
function reg32(reg: tregister): tregister;
begin
reg32 := reg;
end;
{$endif i386}
procedure assign_regvars(p: tnode); procedure assign_regvars(p: tnode);
{ register variables } { register variables }
var var
regvarinfo: pregvarinfo; regvarinfo: pregvarinfo;
i: longint; i: longint;
begin begin
{$ifdef i386}
{ max. optimizations } { max. optimizations }
{ only if no asm is used } { only if no asm is used }
{ and no try statement } { and no try statement }
@ -199,22 +179,20 @@ implementation
regvarinfo^.regvars[i].reg:=varregs[i]; regvarinfo^.regvars[i].reg:=varregs[i];
end end
else else
{$ifdef i386}
if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
(torddef(regvarinfo^.regvars[i].vartype.def).size=1) then (torddef(regvarinfo^.regvars[i].vartype.def).size=1) then
begin begin
{$ifdef i386}
regvarinfo^.regvars[i].reg:=reg32toreg8(varregs[i]); regvarinfo^.regvars[i].reg:=reg32toreg8(varregs[i]);
{$endif}
end 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
(torddef(regvarinfo^.regvars[i].vartype.def).size=2) then (torddef(regvarinfo^.regvars[i].vartype.def).size=2) then
begin begin
{$ifdef i386}
regvarinfo^.regvars[i].reg:=reg32toreg16(varregs[i]); regvarinfo^.regvars[i].reg:=reg32toreg16(varregs[i]);
{$endif}
end end
else else
{$endif i386}
begin begin
regvarinfo^.regvars[i].reg:=varregs[i]; regvarinfo^.regvars[i].reg:=varregs[i];
end; end;
@ -273,23 +251,20 @@ implementation
{$ifdef i386} {$ifdef i386}
{ reserve place on the FPU stack } { reserve place on the FPU stack }
regvarinfo^.fpuregvars[i].reg:=correct_fpuregister(R_ST0,i-1); regvarinfo^.fpuregvars[i].reg:=correct_fpuregister(R_ST0,i-1);
{$endif i386} {$else i386}
{$ifdef m68k}
regvarinfo^.fpuregvars[i].reg:=fpuvarregs[i]; regvarinfo^.fpuregvars[i].reg:=fpuvarregs[i];
{$endif m68k} {$endif i386}
end; end;
end; end;
end; end;
end; end;
{$endif i386}
end; end;
{$ifdef i386}
procedure store_regvar(asml: TAAsmoutput; reg: tregister); procedure store_regvar(asml: TAAsmoutput; reg: tregister);
var var
i: longint; i: longint;
hr: preference; hr: treference;
regvarinfo: pregvarinfo; regvarinfo: pregvarinfo;
vsym: tvarsym; vsym: tvarsym;
begin begin
@ -298,20 +273,25 @@ implementation
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]) and
(reg32(regvarinfo^.regvars[i].reg) = reg) then (makereg32(regvarinfo^.regvars[i].reg) = reg) then
begin begin
if regvar_loaded[reg32(reg)] then if regvar_loaded[makereg32(reg)] then
begin begin
vsym := tvarsym(regvarinfo^.regvars[i]); vsym := tvarsym(regvarinfo^.regvars[i]);
new(hr); { we only have to store the regvar back to memory if it's }
reset_reference(hr^); { possible that it's been modified (JM) }
if vsym.owner.symtabletype in [inlinelocalsymtable,localsymtable] then if not(vsym.varspez in [vs_const,vs_var,vs_out]) then
hr^.offset:=-vsym.address+vsym.owner.address_fixup begin
else hr^.offset:=vsym.address+vsym.owner.address_fixup; reset_reference(hr);
hr^.base:=procinfo^.framepointer; if vsym.owner.symtabletype in [inlinelocalsymtable,localsymtable] then
asml.concat(Taicpu.op_reg_ref(A_MOV,regsize(vsym.reg),vsym.reg,hr)); hr.offset:=-vsym.address+vsym.owner.address_fixup
asml.concat(Tairegalloc.dealloc(reg32(reg))); else hr.offset:=vsym.address+vsym.owner.address_fixup;
regvar_loaded[reg32(reg)] := false; hr.base:=procinfo^.framepointer;
cg.a_load_reg_ref(exprasmlist,def_cgsize(vsym.vartype.def),vsym.reg,hr);
{ asml.concat(Taicpu.op_reg_ref(A_MOV,regsize(vsym.reg),vsym.reg,hr)); }
end;
asml.concat(Tairegalloc.dealloc(makereg32(reg)));
regvar_loaded[makereg32(reg)] := false;
end; end;
break; break;
end; end;
@ -319,43 +299,27 @@ implementation
procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym); procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
var var
hr: preference; hr: treference;
opsize: topsize; opsize: tcgsize;
opcode: tasmop;
begin begin
if not regvar_loaded[reg32(vsym.reg)] then if not regvar_loaded[makereg32(vsym.reg)] then
begin begin
asml.concat(Tairegalloc.alloc(reg32(vsym.reg))); asml.concat(Tairegalloc.alloc(makereg32(vsym.reg)));
{ zero the regvars because the upper 48bits must be clear } reset_reference(hr);
{ 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(Tairegalloc.alloc(reg32(vsym.reg)));
new(hr);
reset_reference(hr^);
if vsym.owner.symtabletype in [inlinelocalsymtable,localsymtable] then if vsym.owner.symtabletype in [inlinelocalsymtable,localsymtable] then
hr^.offset:=-vsym.address+vsym.owner.address_fixup hr.offset:=-vsym.address+vsym.owner.address_fixup
else hr^.offset:=vsym.address+vsym.owner.address_fixup; else hr.offset:=vsym.address+vsym.owner.address_fixup;
hr^.base:=procinfo^.framepointer; hr.base:=procinfo^.framepointer;
asml.concat(Taicpu.op_ref_reg(opcode,opsize,hr,reg32(vsym.reg))); if (vsym.varspez in [vs_var,vs_out]) or
regvar_loaded[reg32(vsym.reg)] := true; ((vsym.varspez=vs_const) and
push_addr_param(vsym.vartype.def)) then
{FIXME!!! Needs to be OS_SIZE_OF_POINTER (JM) }
opsize := OS_32
else
opsize := def_cgsize(vsym.vartype.def);
cg.a_load_ref_reg(exprasmlist,opsize,hr,makereg32(vsym.reg));
{ asml.concat(Taicpu.op_ref_reg(opcode,opsize,hr,makereg32(vsym.reg))); }
regvar_loaded[makereg32(vsym.reg)] := true;
end; end;
end; end;
@ -367,10 +331,10 @@ implementation
regvarinfo := pregvarinfo(aktprocdef.regvarinfo); regvarinfo := pregvarinfo(aktprocdef.regvarinfo);
if not assigned(regvarinfo) then if not assigned(regvarinfo) then
exit; exit;
reg := reg32(reg); reg := makereg32(reg);
for i := 1 to maxvarregs do for i := 1 to maxvarregs do
if assigned(regvarinfo^.regvars[i]) and if assigned(regvarinfo^.regvars[i]) and
(reg32(regvarinfo^.regvars[i].reg) = reg) then (makereg32(regvarinfo^.regvars[i].reg) = reg) then
load_regvar(asml,tvarsym(regvarinfo^.regvars[i])) load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
end; end;
@ -384,17 +348,14 @@ implementation
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]) and
(reg32(regvarinfo^.regvars[i].reg) in [R_EAX,R_EBX,R_ECX,R_EDX]) 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;
{$endif i386}
procedure load_regvars(asml: TAAsmoutput; p: tnode); procedure load_regvars(asml: TAAsmoutput; p: tnode);
var var
i: longint; i: longint;
{hr : treference;}
regvarinfo: pregvarinfo; regvarinfo: pregvarinfo;
begin begin
if (cs_regalloc in aktglobalswitches) and if (cs_regalloc in aktglobalswitches) and
@ -404,25 +365,6 @@ implementation
{ can happen when inlining assembler procedures (JM) } { can happen when inlining assembler procedures (JM) }
if not assigned(regvarinfo) then if not assigned(regvarinfo) then
exit; exit;
{$ifdef m68k}
for i:=1 to maxvarregs do
begin
{ parameter must be load }
if regvarinfo^.regvars_para[i] then
begin
{ procinfo is there actual, }
{ because we can't never be in a }
{ nested procedure }
{ when loading parameter to reg }
new(hr);
reset_reference(hr^);
hr^.offset:=tvarsym(regvarinfo^.regvars[i])^.address+procinfo^.para_offset;
hr^.base:=procinfo^.framepointer;
asml.concat(Taicpu,op_ref_reg(A_MOVE,regsize(regvarinfo^.regvars[i].reg),
hr,regvarinfo^.regvars[i].reg)));
end
end;
{$endif m68k}
for i:=1 to maxvarregs do for i:=1 to maxvarregs do
begin begin
if assigned(regvarinfo^.regvars[i]) then if assigned(regvarinfo^.regvars[i]) then
@ -445,34 +387,14 @@ implementation
regvarinfo^.fpuregvars[i].reg:=correct_fpuregister(R_ST0,i-1); regvarinfo^.fpuregvars[i].reg:=correct_fpuregister(R_ST0,i-1);
asml.concat(Taicpu.op_none(A_FLDZ,S_NO)); asml.concat(Taicpu.op_none(A_FLDZ,S_NO));
{$endif i386} {$endif i386}
{$ifdef dummy}
{ parameter must be load }
if regvarinfo^.fpuregvars_para[i] then
begin
{ procinfo is there actual, }
{ because we can't never be in a }
{ nested procedure }
{ when loading parameter to reg }
new(hr);
reset_reference(hr^);
hr^.offset:=tvarsym(regvarinfo^.regvars[i])^.address+procinfo^.para_offset;
hr^.base:=procinfo^.framepointer;
{$ifdef i386}
asml.concat(Taicpu,op_ref_reg(A_MOV,regsize(regvarinfo^.regvars[i].reg),
hr,regvarinfo^.regvars[i].reg)));
{$endif i386}
{$ifdef m68k}
asml.concat(Taicpu,op_ref_reg(A_MOVE,regsize(regvarinfo^.regvars[i].reg),
hr,regvarinfo^.regvars[i].reg)));
{$endif m68k}
end;
{$endif dummy}
end; end;
end; end;
{$ifdef i386}
if assigned(p) then if assigned(p) then
if cs_asm_source in aktglobalswitches then if cs_asm_source in aktglobalswitches then
asml.insert(Tai_asm_comment.Create(strpnew(tostr(p.registersfpu)+ asml.insert(Tai_asm_comment.Create(strpnew(tostr(p.registersfpu)+
' registers on FPU stack used by temp. expressions'))); ' registers on FPU stack used by temp. expressions')));
{$endif i386}
for i:=1 to maxfpuvarregs do for i:=1 to maxfpuvarregs do
begin begin
if assigned(regvarinfo^.fpuregvars[i]) then if assigned(regvarinfo^.fpuregvars[i]) then
@ -496,7 +418,6 @@ implementation
var var
i: longint; i: longint;
begin begin
{$ifdef i386}
{ can happen when inlining assembler procedures (JM) } { can happen when inlining assembler procedures (JM) }
if not assigned(aktprocdef.regvarinfo) then if not assigned(aktprocdef.regvarinfo) then
exit; exit;
@ -504,23 +425,29 @@ implementation
((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then ((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
with pregvarinfo(aktprocdef.regvarinfo)^ do with pregvarinfo(aktprocdef.regvarinfo)^ do
begin begin
{$ifdef i386}
for i:=1 to maxfpuvarregs do for i:=1 to maxfpuvarregs do
if assigned(fpuregvars[i]) then if assigned(fpuregvars[i]) then
{ ... and clean it up } { ... and clean it up }
asml.concat(Taicpu.op_reg(A_FSTP,S_NO,R_ST0)); asml.concat(Taicpu.op_reg(A_FSTP,S_NO,R_ST0));
{$endif i386}
for i := 1 to maxvarregs do for i := 1 to maxvarregs do
if assigned(regvars[i]) and if assigned(regvars[i]) and
(regvar_loaded[reg32(regvars[i].reg)]) then (regvar_loaded[makereg32(regvars[i].reg)]) then
asml.concat(Tairegalloc.dealloc(reg32(regvars[i].reg))); asml.concat(Tairegalloc.dealloc(makereg32(regvars[i].reg)));
end; end;
{$endif i386}
end; end;
end. end.
{ {
$Log$ $Log$
Revision 1.19 2001-11-02 22:58:06 peter Revision 1.20 2001-11-05 16:49:32 jonas
* constant regvars (addresses of var/out para's and const para's) aren't
saved to memory anymore when their register will be destroyed
* unit has been made mostly processor independent
Revision 1.19 2001/11/02 22:58:06 peter
* procsym definition rewrite * procsym definition rewrite
Revision 1.18 2001/08/26 13:36:49 florian Revision 1.18 2001/08/26 13:36:49 florian