mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-22 04:09:30 +02:00
* 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:
parent
9b628f6409
commit
4d0eae9a7c
@ -35,12 +35,10 @@ interface
|
||||
procedure assign_regvars(p: tnode);
|
||||
procedure load_regvars(asml: TAAsmoutput; p: tnode);
|
||||
procedure cleanup_regvars(asml: TAAsmoutput);
|
||||
{$ifdef i386}
|
||||
procedure store_regvar(asml: TAAsmoutput; reg: tregister);
|
||||
procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
|
||||
procedure load_regvar_reg(asml: TAAsmoutput; reg: tregister);
|
||||
procedure load_all_regvars(asml: TAAsmoutput);
|
||||
{$endif i386}
|
||||
|
||||
implementation
|
||||
|
||||
@ -48,7 +46,7 @@ implementation
|
||||
globtype,systems,comphook,
|
||||
cutils,cclasses,verbose,globals,
|
||||
symconst,symbase,symtype,symdef,types,
|
||||
cgbase,cpuasm,tgcpu;
|
||||
cgbase,cpuasm,tgcpu,cgobj,cgcpu,cga;
|
||||
|
||||
var
|
||||
parasym : boolean;
|
||||
@ -130,30 +128,12 @@ implementation
|
||||
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);
|
||||
{ register variables }
|
||||
var
|
||||
regvarinfo: pregvarinfo;
|
||||
i: longint;
|
||||
begin
|
||||
{$ifdef i386}
|
||||
{ max. optimizations }
|
||||
{ only if no asm is used }
|
||||
{ and no try statement }
|
||||
@ -199,22 +179,20 @@ implementation
|
||||
regvarinfo^.regvars[i].reg:=varregs[i];
|
||||
end
|
||||
else
|
||||
{$ifdef i386}
|
||||
if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
|
||||
(torddef(regvarinfo^.regvars[i].vartype.def).size=1) then
|
||||
begin
|
||||
{$ifdef i386}
|
||||
regvarinfo^.regvars[i].reg:=reg32toreg8(varregs[i]);
|
||||
{$endif}
|
||||
end
|
||||
else
|
||||
if (regvarinfo^.regvars[i].vartype.def.deftype in [orddef,enumdef]) and
|
||||
(torddef(regvarinfo^.regvars[i].vartype.def).size=2) then
|
||||
begin
|
||||
{$ifdef i386}
|
||||
regvarinfo^.regvars[i].reg:=reg32toreg16(varregs[i]);
|
||||
{$endif}
|
||||
end
|
||||
else
|
||||
{$endif i386}
|
||||
begin
|
||||
regvarinfo^.regvars[i].reg:=varregs[i];
|
||||
end;
|
||||
@ -273,23 +251,20 @@ implementation
|
||||
{$ifdef i386}
|
||||
{ reserve place on the FPU stack }
|
||||
regvarinfo^.fpuregvars[i].reg:=correct_fpuregister(R_ST0,i-1);
|
||||
{$endif i386}
|
||||
{$ifdef m68k}
|
||||
{$else i386}
|
||||
regvarinfo^.fpuregvars[i].reg:=fpuvarregs[i];
|
||||
{$endif m68k}
|
||||
{$endif i386}
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
{$endif i386}
|
||||
end;
|
||||
|
||||
|
||||
{$ifdef i386}
|
||||
procedure store_regvar(asml: TAAsmoutput; reg: tregister);
|
||||
var
|
||||
i: longint;
|
||||
hr: preference;
|
||||
hr: treference;
|
||||
regvarinfo: pregvarinfo;
|
||||
vsym: tvarsym;
|
||||
begin
|
||||
@ -298,20 +273,25 @@ implementation
|
||||
exit;
|
||||
for i := 1 to maxvarregs do
|
||||
if assigned(regvarinfo^.regvars[i]) and
|
||||
(reg32(regvarinfo^.regvars[i].reg) = reg) then
|
||||
(makereg32(regvarinfo^.regvars[i].reg) = reg) then
|
||||
begin
|
||||
if regvar_loaded[reg32(reg)] then
|
||||
if regvar_loaded[makereg32(reg)] then
|
||||
begin
|
||||
vsym := tvarsym(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(Taicpu.op_reg_ref(A_MOV,regsize(vsym.reg),vsym.reg,hr));
|
||||
asml.concat(Tairegalloc.dealloc(reg32(reg)));
|
||||
regvar_loaded[reg32(reg)] := false;
|
||||
{ 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
|
||||
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;
|
||||
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;
|
||||
break;
|
||||
end;
|
||||
@ -319,43 +299,27 @@ implementation
|
||||
|
||||
procedure load_regvar(asml: TAAsmoutput; vsym: tvarsym);
|
||||
var
|
||||
hr: preference;
|
||||
opsize: topsize;
|
||||
opcode: tasmop;
|
||||
hr: treference;
|
||||
opsize: tcgsize;
|
||||
begin
|
||||
if not regvar_loaded[reg32(vsym.reg)] then
|
||||
if not regvar_loaded[makereg32(vsym.reg)] then
|
||||
begin
|
||||
asml.concat(Tairegalloc.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(Tairegalloc.alloc(reg32(vsym.reg)));
|
||||
new(hr);
|
||||
reset_reference(hr^);
|
||||
asml.concat(Tairegalloc.alloc(makereg32(vsym.reg)));
|
||||
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(Taicpu.op_ref_reg(opcode,opsize,hr,reg32(vsym.reg)));
|
||||
regvar_loaded[reg32(vsym.reg)] := true;
|
||||
hr.offset:=-vsym.address+vsym.owner.address_fixup
|
||||
else hr.offset:=vsym.address+vsym.owner.address_fixup;
|
||||
hr.base:=procinfo^.framepointer;
|
||||
if (vsym.varspez in [vs_var,vs_out]) or
|
||||
((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;
|
||||
|
||||
@ -367,10 +331,10 @@ implementation
|
||||
regvarinfo := pregvarinfo(aktprocdef.regvarinfo);
|
||||
if not assigned(regvarinfo) then
|
||||
exit;
|
||||
reg := reg32(reg);
|
||||
reg := makereg32(reg);
|
||||
for i := 1 to maxvarregs do
|
||||
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]))
|
||||
end;
|
||||
|
||||
@ -384,17 +348,14 @@ implementation
|
||||
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
|
||||
(makereg32(regvarinfo^.regvars[i].reg) in [R_EAX,R_EBX,R_ECX,R_EDX]) then
|
||||
load_regvar(asml,tvarsym(regvarinfo^.regvars[i]))
|
||||
end;
|
||||
|
||||
{$endif i386}
|
||||
|
||||
|
||||
procedure load_regvars(asml: TAAsmoutput; p: tnode);
|
||||
var
|
||||
i: longint;
|
||||
{hr : treference;}
|
||||
regvarinfo: pregvarinfo;
|
||||
begin
|
||||
if (cs_regalloc in aktglobalswitches) and
|
||||
@ -404,25 +365,6 @@ 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
|
||||
{ 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
|
||||
begin
|
||||
if assigned(regvarinfo^.regvars[i]) then
|
||||
@ -445,34 +387,14 @@ implementation
|
||||
regvarinfo^.fpuregvars[i].reg:=correct_fpuregister(R_ST0,i-1);
|
||||
asml.concat(Taicpu.op_none(A_FLDZ,S_NO));
|
||||
{$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;
|
||||
{$ifdef i386}
|
||||
if assigned(p) then
|
||||
if cs_asm_source in aktglobalswitches then
|
||||
asml.insert(Tai_asm_comment.Create(strpnew(tostr(p.registersfpu)+
|
||||
' registers on FPU stack used by temp. expressions')));
|
||||
{$endif i386}
|
||||
for i:=1 to maxfpuvarregs do
|
||||
begin
|
||||
if assigned(regvarinfo^.fpuregvars[i]) then
|
||||
@ -496,7 +418,6 @@ implementation
|
||||
var
|
||||
i: longint;
|
||||
begin
|
||||
{$ifdef i386}
|
||||
{ can happen when inlining assembler procedures (JM) }
|
||||
if not assigned(aktprocdef.regvarinfo) then
|
||||
exit;
|
||||
@ -504,23 +425,29 @@ implementation
|
||||
((procinfo^.flags and (pi_uses_asm or pi_uses_exceptions))=0) then
|
||||
with pregvarinfo(aktprocdef.regvarinfo)^ do
|
||||
begin
|
||||
{$ifdef i386}
|
||||
for i:=1 to maxfpuvarregs do
|
||||
if assigned(fpuregvars[i]) then
|
||||
{ ... and clean it up }
|
||||
asml.concat(Taicpu.op_reg(A_FSTP,S_NO,R_ST0));
|
||||
{$endif i386}
|
||||
for i := 1 to maxvarregs do
|
||||
if assigned(regvars[i]) and
|
||||
(regvar_loaded[reg32(regvars[i].reg)]) then
|
||||
asml.concat(Tairegalloc.dealloc(reg32(regvars[i].reg)));
|
||||
(regvar_loaded[makereg32(regvars[i].reg)]) then
|
||||
asml.concat(Tairegalloc.dealloc(makereg32(regvars[i].reg)));
|
||||
end;
|
||||
{$endif i386}
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
{
|
||||
$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
|
||||
|
||||
Revision 1.18 2001/08/26 13:36:49 florian
|
||||
|
Loading…
Reference in New Issue
Block a user