mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-16 12:59:24 +02:00
* rg[tregistertype] added in tcg
This commit is contained in:
parent
8b4a122d49
commit
bce5a1e252
@ -59,7 +59,9 @@ unit cgobj;
|
||||
sould be @link(tcg64f32) and not @var(tcg).
|
||||
}
|
||||
tcg = class
|
||||
public
|
||||
alignment : talignment;
|
||||
rg : array[tregistertype] of trgobj;
|
||||
t_times:cardinal;
|
||||
{************************************************}
|
||||
{ basic routines }
|
||||
@ -71,28 +73,28 @@ unit cgobj;
|
||||
procedure done_register_allocators;virtual;abstract;
|
||||
|
||||
{# Gets a register suitable to do integer operations on.}
|
||||
function getintregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract;
|
||||
function getintregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;
|
||||
{# Gets a register suitable to do integer operations on.}
|
||||
function getaddressregister(list:Taasmoutput):Tregister;virtual;
|
||||
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract;
|
||||
function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract;
|
||||
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;
|
||||
function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;
|
||||
function getflagregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract;
|
||||
{Does the generic cg need SIMD registers, like getmmxregister? Or should
|
||||
the cpu specific child cg object have such a method?}
|
||||
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;abstract;
|
||||
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
|
||||
procedure ungetreference(list:Taasmoutput;const r:Treference);virtual;
|
||||
|
||||
procedure add_move_instruction(instr:Taicpu);virtual;abstract;
|
||||
procedure add_move_instruction(instr:Taicpu);virtual;
|
||||
|
||||
function uses_registers(rt:Tregistertype):boolean;virtual;abstract;
|
||||
function uses_registers(rt:Tregistertype):boolean;virtual;
|
||||
{# Get a specific register.}
|
||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;abstract;
|
||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;
|
||||
{# Get multiple registers specified.}
|
||||
procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);virtual;abstract;
|
||||
procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);virtual;
|
||||
{# Free multiple registers specified.}
|
||||
procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);virtual;abstract;
|
||||
procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);virtual;
|
||||
|
||||
procedure do_register_allocation(list:Taasmoutput;headertai:tai);virtual;abstract;
|
||||
procedure do_register_allocation(list:Taasmoutput;headertai:tai);virtual;
|
||||
|
||||
function makeregsize(reg:Tregister;size:Tcgsize):Tregister;
|
||||
|
||||
@ -550,24 +552,74 @@ implementation
|
||||
******************************************************************************}
|
||||
|
||||
constructor tcg.create;
|
||||
begin
|
||||
end;
|
||||
|
||||
begin
|
||||
end;
|
||||
|
||||
function Tcg.makeregsize(reg:Tregister;size:Tcgsize):Tregister;
|
||||
var
|
||||
subreg:Tsubregister;
|
||||
begin
|
||||
subreg:=cgsize2subreg(size);
|
||||
result:=reg;
|
||||
setsubreg(result,subreg);
|
||||
end;
|
||||
|
||||
var subreg:Tsubregister;
|
||||
|
||||
begin
|
||||
subreg:=cgsize2subreg(size);
|
||||
result:=reg;
|
||||
setsubreg(result,subreg);
|
||||
end;
|
||||
{*****************************************************************************
|
||||
register allocation
|
||||
******************************************************************************}
|
||||
|
||||
function tcg.getintregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
if not assigned(rg[R_INTREGISTER]) then
|
||||
internalerror(200312122);
|
||||
result:=rg[R_INTREGISTER].getregister(list,cgsize2subreg(size));
|
||||
end;
|
||||
|
||||
|
||||
function tcg.getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
if not assigned(rg[R_FPUREGISTER]) then
|
||||
internalerror(200312123);
|
||||
result:=rg[R_FPUREGISTER].getregister(list,cgsize2subreg(size));
|
||||
end;
|
||||
|
||||
|
||||
function tcg.getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
if not assigned(rg[R_MMREGISTER]) then
|
||||
internalerror(200312124);
|
||||
result:=rg[R_MMREGISTER].getregister(list,cgsize2subreg(size));
|
||||
end;
|
||||
|
||||
|
||||
function tcg.getaddressregister(list:Taasmoutput):Tregister;
|
||||
begin
|
||||
result:=getintregister(list,OS_ADDR);
|
||||
if assigned(rg[R_ADDRESSREGISTER]) then
|
||||
result:=rg[R_ADDRESSREGISTER].getregister(list,R_SUBWHOLE)
|
||||
else
|
||||
begin
|
||||
if not assigned(rg[R_INTREGISTER]) then
|
||||
internalerror(200312121);
|
||||
result:=rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||
begin
|
||||
if not assigned(rg[getregtype(r)]) then
|
||||
internalerror(200312125);
|
||||
rg[getregtype(r)].getexplicitregister(list,r);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.ungetregister(list:Taasmoutput;r:Tregister);
|
||||
begin
|
||||
if not assigned(rg[getregtype(r)]) then
|
||||
internalerror(200312126);
|
||||
rg[getregtype(r)].ungetregister(list,r);
|
||||
end;
|
||||
|
||||
|
||||
@ -578,6 +630,61 @@ implementation
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
|
||||
begin
|
||||
if assigned(rg[rt]) then
|
||||
rg[rt].allocexplicitregisters(list,r)
|
||||
else
|
||||
internalerror(200310092);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
|
||||
begin
|
||||
if assigned(rg[rt]) then
|
||||
rg[rt].deallocexplicitregisters(list,r)
|
||||
else
|
||||
internalerror(200310093);
|
||||
end;
|
||||
|
||||
|
||||
function tcg.uses_registers(rt:Tregistertype):boolean;
|
||||
begin
|
||||
if assigned(rg[rt]) then
|
||||
result:=rg[rt].uses_registers
|
||||
else
|
||||
internalerror(200310094);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.add_move_instruction(instr:Taicpu);
|
||||
var
|
||||
rt : tregistertype;
|
||||
begin
|
||||
rt:=getregtype(instr.oper[O_MOV_SOURCE]^.reg);
|
||||
if assigned(rg[rt]) then
|
||||
rg[rt].add_move_instruction(instr)
|
||||
else
|
||||
internalerror(200310095);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.do_register_allocation(list:Taasmoutput;headertai:tai);
|
||||
var
|
||||
rt : tregistertype;
|
||||
begin
|
||||
for rt:=low(tregistertype) to high(tregistertype) do
|
||||
begin
|
||||
if assigned(rg[rt]) then
|
||||
begin
|
||||
rg[rt].check_unreleasedregs;
|
||||
rg[rt].do_register_allocation(list,headertai);
|
||||
rg[rt].translate_registers(list);
|
||||
end;
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcg.a_reg_alloc(list : taasmoutput;r : tregister);
|
||||
begin
|
||||
list.concat(tai_regalloc.alloc(r));
|
||||
@ -619,11 +726,10 @@ implementation
|
||||
end;
|
||||
end;
|
||||
|
||||
procedure tcg.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
|
||||
|
||||
procedure tcg.a_param_const(list : taasmoutput;size : tcgsize;a : aword;const locpara : tparalocation);
|
||||
var
|
||||
hr : tregister;
|
||||
|
||||
begin
|
||||
hr:=getintregister(list,size);
|
||||
a_load_const_reg(list,size,a,hr);
|
||||
@ -1835,7 +1941,10 @@ finalization
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.137 2003-12-06 22:11:47 jonas
|
||||
Revision 1.138 2003-12-12 17:16:17 peter
|
||||
* rg[tregistertype] added in tcg
|
||||
|
||||
Revision 1.137 2003/12/06 22:11:47 jonas
|
||||
+ allocate volatile registers around calls to procedures declared with
|
||||
"saveregisters" on non-x86 processors
|
||||
|
||||
|
@ -34,24 +34,10 @@ unit cgcpu;
|
||||
|
||||
type
|
||||
tcgppc = class(tcg)
|
||||
rgint,
|
||||
rgflags,
|
||||
rgmm,
|
||||
rgfpu : trgcpu;
|
||||
procedure init_register_allocators;override;
|
||||
procedure done_register_allocators;override;
|
||||
|
||||
function getintregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
|
||||
procedure ungetregister(list:Taasmoutput;r:Tregister);override;
|
||||
procedure ungetreference(list:Taasmoutput;const r:Treference);override;
|
||||
procedure add_move_instruction(instr:Taicpu);override;
|
||||
procedure do_register_allocation(list:Taasmoutput;headertai:tai);override;
|
||||
procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
|
||||
procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
|
||||
function uses_registers(rt:Tregistertype):boolean;override;
|
||||
|
||||
{ passing parameters, per default the parameter is pushed }
|
||||
{ nr gives the number of the parameter (enumerated from }
|
||||
@ -180,155 +166,37 @@ const
|
||||
|
||||
procedure tcgppc.init_register_allocators;
|
||||
begin
|
||||
rgint:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,
|
||||
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,
|
||||
[RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,
|
||||
RS_R9,RS_R10,RS_R11,RS_R12,RS_R31,RS_R30,RS_R29,
|
||||
RS_R28,RS_R27,RS_R26,RS_R25,RS_R24,RS_R23,RS_R22,
|
||||
RS_R21,RS_R20,RS_R19,RS_R18,RS_R17,RS_R16,RS_R15,
|
||||
RS_R14,RS_R13],first_int_imreg,[]);
|
||||
rgfpu:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
|
||||
rg[R_FPUREGISTER]:=trgcpu.create(R_FPUREGISTER,R_SUBNONE,
|
||||
[RS_F0,RS_F1,RS_F2,RS_F3,RS_F4,RS_F5,RS_F6,RS_F7,RS_F8,RS_F9,
|
||||
RS_F10,RS_F11,RS_F12,RS_F13,RS_F31,RS_F30,RS_F29,RS_F28,RS_F27,
|
||||
RS_F26,RS_F25,RS_F24,RS_F23,RS_F22,RS_F21,RS_F20,RS_F19,RS_F18,
|
||||
RS_F17,RS_F16,RS_F15,RS_F14],first_fpu_imreg,[]);
|
||||
{$warning FIX ME}
|
||||
rgmm:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
|
||||
rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,
|
||||
[RS_M0,RS_M1,RS_M2],first_mm_imreg,[]);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.done_register_allocators;
|
||||
begin
|
||||
rgint.free;
|
||||
rgmm.free;
|
||||
rgfpu.free;
|
||||
end;
|
||||
|
||||
|
||||
function tcgppc.getintregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=rgint.getregister(list,cgsize2subreg(size));
|
||||
end;
|
||||
|
||||
|
||||
function tcgppc.getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=rgfpu.getregister(list,R_SUBWHOLE);
|
||||
end;
|
||||
|
||||
|
||||
function tcgppc.getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=rgmm.getregister(list,R_SUBNONE);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||
begin
|
||||
case getregtype(r) of
|
||||
R_INTREGISTER :
|
||||
rgint.getexplicitregister(list,r);
|
||||
R_MMREGISTER :
|
||||
rgmm.getexplicitregister(list,r);
|
||||
R_FPUREGISTER :
|
||||
rgfpu.getexplicitregister(list,r);
|
||||
else
|
||||
internalerror(200310091);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.ungetregister(list:Taasmoutput;r:Tregister);
|
||||
begin
|
||||
case getregtype(r) of
|
||||
R_INTREGISTER :
|
||||
rgint.ungetregister(list,r);
|
||||
R_FPUREGISTER :
|
||||
rgfpu.ungetregister(list,r);
|
||||
R_MMREGISTER :
|
||||
rgmm.ungetregister(list,r);
|
||||
else
|
||||
internalerror(200310091);
|
||||
end;
|
||||
rg[R_INTREGISTER].free;
|
||||
rg[R_FPUREGISTER].free;
|
||||
rg[R_MMREGISTER].free;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.ungetreference(list:Taasmoutput;const r:Treference);
|
||||
begin
|
||||
if r.base<>NR_NO then
|
||||
rgint.ungetregister(list,r.base);
|
||||
ungetregister(list,r.base);
|
||||
if r.index<>NR_NO then
|
||||
rgint.ungetregister(list,r.index);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
|
||||
begin
|
||||
case rt of
|
||||
R_INTREGISTER :
|
||||
rgint.allocexplicitregisters(list,r);
|
||||
R_FPUREGISTER :
|
||||
rgfpu.allocexplicitregisters(list,r);
|
||||
R_MMREGISTER :
|
||||
rgmm.allocexplicitregisters(list,r);
|
||||
else
|
||||
internalerror(200310092);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
|
||||
begin
|
||||
case rt of
|
||||
R_INTREGISTER :
|
||||
rgint.deallocexplicitregisters(list,r);
|
||||
R_FPUREGISTER :
|
||||
rgfpu.deallocexplicitregisters(list,r);
|
||||
R_MMREGISTER :
|
||||
rgmm.deallocexplicitregisters(list,r);
|
||||
else
|
||||
internalerror(200310093);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
function tcgppc.uses_registers(rt:Tregistertype):boolean;
|
||||
begin
|
||||
case rt of
|
||||
R_INTREGISTER :
|
||||
result:=rgint.uses_registers;
|
||||
R_MMREGISTER :
|
||||
result:=rgmm.uses_registers;
|
||||
R_FPUREGISTER :
|
||||
result:=rgfpu.uses_registers;
|
||||
else
|
||||
internalerror(200310094);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.add_move_instruction(instr:Taicpu);
|
||||
begin
|
||||
rgint.add_move_instruction(instr);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgppc.do_register_allocation(list:Taasmoutput;headertai:tai);
|
||||
begin
|
||||
{ Int }
|
||||
rgint.check_unreleasedregs;
|
||||
rgint.do_register_allocation(list,headertai);
|
||||
rgint.translate_registers(list);
|
||||
|
||||
{ FPU }
|
||||
rgfpu.check_unreleasedregs;
|
||||
rgfpu.do_register_allocation(list,headertai);
|
||||
rgfpu.translate_registers(list);
|
||||
|
||||
{ MM }
|
||||
rgmm.check_unreleasedregs;
|
||||
rgmm.do_register_allocation(list,headertai);
|
||||
rgmm.translate_registers(list);
|
||||
ungetregister(list,r.index);
|
||||
end;
|
||||
|
||||
|
||||
@ -367,10 +235,10 @@ const
|
||||
reference_reset(ref);
|
||||
ref.base:=locpara.reference.index;
|
||||
ref.offset:=locpara.reference.offset;
|
||||
tmpreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_load_ref_reg(list,size,size,r,tmpreg);
|
||||
a_load_reg_ref(list,size,size,tmpreg,ref);
|
||||
rgint.ungetregister(list,tmpreg);
|
||||
rg[R_INTREGISTER].ungetregister(list,tmpreg);
|
||||
end;
|
||||
LOC_FPUREGISTER,LOC_CFPUREGISTER:
|
||||
case size of
|
||||
@ -399,10 +267,10 @@ const
|
||||
reference_reset(ref);
|
||||
ref.base := locpara.reference.index;
|
||||
ref.offset := locpara.reference.offset;
|
||||
tmpreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_loadaddr_ref_reg(list,r,tmpreg);
|
||||
a_load_reg_ref(list,OS_ADDR,OS_ADDR,tmpreg,ref);
|
||||
rgint.ungetregister(list,tmpreg);
|
||||
rg[R_INTREGISTER].ungetregister(list,tmpreg);
|
||||
end;
|
||||
else
|
||||
internalerror(2002080701);
|
||||
@ -438,14 +306,14 @@ const
|
||||
{Generate instruction to load the procedure address from
|
||||
the transition vector.}
|
||||
//TODO: Support cross-TOC calls.
|
||||
tmpreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
reference_reset(tmpref);
|
||||
tmpref.offset := 0;
|
||||
//tmpref.symaddr := refs_full;
|
||||
tmpref.base:= reg;
|
||||
list.concat(taicpu.op_reg_ref(A_LWZ,tmpreg,tmpref));
|
||||
list.concat(taicpu.op_reg(A_MTCTR,tmpreg));
|
||||
rgint.ungetregister(list,tmpreg);
|
||||
rg[R_INTREGISTER].ungetregister(list,tmpreg);
|
||||
end
|
||||
else
|
||||
list.concat(taicpu.op_reg(A_MTCTR,reg));
|
||||
@ -506,7 +374,7 @@ const
|
||||
op := storeinstr[tcgsize2unsigned[tosize],ref2.index<>NR_NO,false];
|
||||
a_load_store(list,op,reg,ref2);
|
||||
if freereg then
|
||||
rgint.ungetregister(list,ref2.base);
|
||||
rg[R_INTREGISTER].ungetregister(list,ref2.base);
|
||||
End;
|
||||
|
||||
|
||||
@ -544,7 +412,7 @@ const
|
||||
op := loadinstr[fromsize,ref2.index<>NR_NO,false];
|
||||
a_load_store(list,op,reg,ref2);
|
||||
if freereg then
|
||||
rgint.ungetregister(list,ref2.base);
|
||||
rg[R_INTREGISTER].ungetregister(list,ref2.base);
|
||||
{ sign extend shortint if necessary, since there is no }
|
||||
{ load instruction that does that automatically (JM) }
|
||||
if fromsize = OS_S8 then
|
||||
@ -579,7 +447,7 @@ const
|
||||
else internalerror(2002090901);
|
||||
end;
|
||||
list.concat(instr);
|
||||
rgint.add_move_instruction(instr);
|
||||
rg[R_INTREGISTER].add_move_instruction(instr);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -619,7 +487,7 @@ const
|
||||
op := fpuloadinstr[size,ref2.index <> NR_NO,false];
|
||||
a_load_store(list,op,reg,ref2);
|
||||
if freereg then
|
||||
rgint.ungetregister(list,ref2.base);
|
||||
rg[R_INTREGISTER].ungetregister(list,ref2.base);
|
||||
end;
|
||||
|
||||
|
||||
@ -643,7 +511,7 @@ const
|
||||
op := fpustoreinstr[size,ref2.index <> NR_NO,false];
|
||||
a_load_store(list,op,reg,ref2);
|
||||
if freereg then
|
||||
rgint.ungetregister(list,ref2.base);
|
||||
rg[R_INTREGISTER].ungetregister(list,ref2.base);
|
||||
end;
|
||||
|
||||
|
||||
@ -799,11 +667,11 @@ const
|
||||
if gotrlwi and
|
||||
(src = dst) then
|
||||
begin
|
||||
scratchreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
scratchreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
list.concat(taicpu.op_reg_const(A_LI,scratchreg,-1));
|
||||
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,dst,
|
||||
scratchreg,0,l1,l2));
|
||||
rgint.ungetregister(list,scratchreg);
|
||||
rg[R_INTREGISTER].ungetregister(list,scratchreg);
|
||||
end
|
||||
else
|
||||
do_lo_hi;
|
||||
@ -833,10 +701,10 @@ const
|
||||
{ perform the operation }
|
||||
if useReg then
|
||||
begin
|
||||
scratchreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
scratchreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_load_const_reg(list,OS_32,a,scratchreg);
|
||||
a_op_reg_reg_reg(list,op,OS_32,scratchreg,src,dst);
|
||||
rgint.ungetregister(list,scratchreg);
|
||||
rg[R_INTREGISTER].ungetregister(list,scratchreg);
|
||||
end;
|
||||
end;
|
||||
|
||||
@ -881,20 +749,20 @@ const
|
||||
list.concat(taicpu.op_reg_reg_const(A_CMPWI,NR_CR0,reg,longint(a)))
|
||||
else
|
||||
begin
|
||||
scratch_register := rgint.getregister(list,R_SUBWHOLE);
|
||||
scratch_register := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_load_const_reg(list,OS_32,a,scratch_register);
|
||||
list.concat(taicpu.op_reg_reg_reg(A_CMPW,NR_CR0,reg,scratch_register));
|
||||
rgint.ungetregister(list,scratch_register);
|
||||
rg[R_INTREGISTER].ungetregister(list,scratch_register);
|
||||
end
|
||||
else
|
||||
if (a <= $ffff) then
|
||||
list.concat(taicpu.op_reg_reg_const(A_CMPLWI,NR_CR0,reg,a))
|
||||
else
|
||||
begin
|
||||
scratch_register := rgint.getregister(list,R_SUBWHOLE);
|
||||
scratch_register := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_load_const_reg(list,OS_32,a,scratch_register);
|
||||
list.concat(taicpu.op_reg_reg_reg(A_CMPLW,NR_CR0,reg,scratch_register));
|
||||
rgint.ungetregister(list,scratch_register);
|
||||
rg[R_INTREGISTER].ungetregister(list,scratch_register);
|
||||
end;
|
||||
a_jmp(list,A_BC,TOpCmp2AsmCond[cmp_op],0,l);
|
||||
end;
|
||||
@ -1088,7 +956,7 @@ const
|
||||
{ FIXME: has to be R_F8 instad of R_F14 for SYSV abi }
|
||||
for regcounter:=RS_F14 to RS_F31 do
|
||||
begin
|
||||
if regcounter in rgfpu.used_in_proc then
|
||||
if regcounter in rg[R_FPUREGISTER].used_in_proc then
|
||||
begin
|
||||
usesfpr:= true;
|
||||
firstregfpu:=regcounter;
|
||||
@ -1100,7 +968,7 @@ const
|
||||
if not (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
for regcounter2:=RS_R13 to RS_R31 do
|
||||
begin
|
||||
if regcounter2 in rgint.used_in_proc then
|
||||
if regcounter2 in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
usesgpr:=true;
|
||||
firstreggpr:=regcounter2;
|
||||
@ -1183,7 +1051,7 @@ const
|
||||
reference_reset_base(href,NR_R12,-8);
|
||||
for regcounter:=firstregfpu to RS_F31 do
|
||||
begin
|
||||
if regcounter in rgfpu.used_in_proc then
|
||||
if regcounter in rg[R_FPUREGISTER].used_in_proc then
|
||||
begin
|
||||
a_loadfpu_reg_ref(list,OS_F64,newreg(R_FPUREGISTER,regcounter,R_SUBNONE),href);
|
||||
dec(href.offset,8);
|
||||
@ -1209,7 +1077,7 @@ const
|
||||
reference_reset_base(href,NR_R12,-4);
|
||||
for regcounter2:=RS_R13 to RS_R31 do
|
||||
begin
|
||||
if regcounter2 in rgint.used_in_proc then
|
||||
if regcounter2 in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
usesgpr:=true;
|
||||
a_load_reg_ref(list,OS_INT,OS_INT,newreg(R_INTREGISTER,regcounter2,R_SUBNONE),href);
|
||||
@ -1242,7 +1110,7 @@ const
|
||||
cg.a_load_ref_ref(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,href);
|
||||
}
|
||||
cg.a_load_ref_reg(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,href2,NR_R0);
|
||||
cg.a_load_reg_ref(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,NR_R0,href);
|
||||
cg.a_load_reg_ref(list,hp.paraloc[calleeside].size,hp.paraloc[calleeside].size,NR_R0,href);
|
||||
end
|
||||
{$ifdef dummy}
|
||||
else if (hp.calleeparaloc.loc in [LOC_REGISTER,LOC_CREGISTER]) then
|
||||
@ -1306,7 +1174,7 @@ const
|
||||
if not (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
for regcounter:=RS_F14 to RS_F31 do
|
||||
begin
|
||||
if regcounter in rgfpu.used_in_proc then
|
||||
if regcounter in rg[R_FPUREGISTER].used_in_proc then
|
||||
begin
|
||||
usesfpr:=true;
|
||||
firstregfpu:=regcounter;
|
||||
@ -1318,7 +1186,7 @@ const
|
||||
if not (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
for regcounter2:=RS_R13 to RS_R31 do
|
||||
begin
|
||||
if regcounter2 in rgint.used_in_proc then
|
||||
if regcounter2 in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
usesgpr:=true;
|
||||
firstreggpr:=regcounter2;
|
||||
@ -1339,7 +1207,7 @@ const
|
||||
reference_reset_base(href,NR_R12,-8);
|
||||
for regcounter := firstregfpu to RS_F31 do
|
||||
begin
|
||||
if regcounter in rgfpu.used_in_proc then
|
||||
if regcounter in rg[R_FPUREGISTER].used_in_proc then
|
||||
begin
|
||||
a_loadfpu_ref_reg(list,OS_F64,href,newreg(R_FPUREGISTER,regcounter,R_SUBNONE));
|
||||
dec(href.offset,8);
|
||||
@ -1352,7 +1220,7 @@ const
|
||||
|
||||
for regcounter2:=RS_R13 to RS_R31 do
|
||||
begin
|
||||
if regcounter2 in rgint.used_in_proc then
|
||||
if regcounter2 in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
usesgpr:=true;
|
||||
a_load_ref_reg(list,OS_INT,OS_INT,href,newreg(R_INTREGISTER,regcounter2,R_SUBNONE));
|
||||
@ -1437,7 +1305,7 @@ const
|
||||
if not (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
for regcounter:=RS_F14 to RS_F31 do
|
||||
begin
|
||||
if regcounter in rgfpu.used_in_proc then
|
||||
if regcounter in rg[R_FPUREGISTER].used_in_proc then
|
||||
begin
|
||||
usesfpr:=true;
|
||||
firstregfpu:=regcounter;
|
||||
@ -1448,7 +1316,7 @@ const
|
||||
if not (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
for regcounter2:=RS_R13 to RS_R31 do
|
||||
begin
|
||||
if regcounter2 in rgint.used_in_proc then
|
||||
if regcounter2 in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
usesgpr:=true;
|
||||
firstreggpr:=regcounter2;
|
||||
@ -1506,7 +1374,7 @@ const
|
||||
if not (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
for regcounter:=RS_F14 to RS_F31 do
|
||||
begin
|
||||
if regcounter in rgfpu.used_in_proc then
|
||||
if regcounter in rg[R_FPUREGISTER].used_in_proc then
|
||||
begin
|
||||
usesfpr:=true;
|
||||
firstregfpu:=regcounter;
|
||||
@ -1518,7 +1386,7 @@ const
|
||||
if not (po_assembler in current_procinfo.procdef.procoptions) then
|
||||
for regcounter2:=RS_R13 to RS_R31 do
|
||||
begin
|
||||
if regcounter2 in rgint.used_in_proc then
|
||||
if regcounter2 in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
usesgpr:=true;
|
||||
firstreggpr:=regcounter2;
|
||||
@ -1761,7 +1629,7 @@ const
|
||||
ref2.base,tmpref));
|
||||
if freereg then
|
||||
begin
|
||||
rgint.ungetregister(list,ref2.base);
|
||||
rg[R_INTREGISTER].ungetregister(list,ref2.base);
|
||||
freereg := false;
|
||||
end;
|
||||
end
|
||||
@ -1787,7 +1655,7 @@ const
|
||||
(r <> ref2.base) then
|
||||
list.concat(taicpu.op_reg_reg(A_MR,r,ref2.base));
|
||||
if freereg then
|
||||
rgint.ungetregister(list,ref2.base);
|
||||
rg[R_INTREGISTER].ungetregister(list,ref2.base);
|
||||
end;
|
||||
|
||||
{ ************* concatcopy ************ }
|
||||
@ -1853,7 +1721,7 @@ const
|
||||
{ load the address of source into src.base }
|
||||
if loadref then
|
||||
begin
|
||||
src.base := rgint.getregister(list,R_SUBWHOLE);
|
||||
src.base := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_load_ref_reg(list,OS_32,OS_32,source,src.base);
|
||||
orgsrc := false;
|
||||
end
|
||||
@ -1862,7 +1730,7 @@ const
|
||||
((source.index <> NR_NO) and
|
||||
((source.offset + longint(len)) > high(smallint))) then
|
||||
begin
|
||||
src.base := rgint.getregister(list,R_SUBWHOLE);
|
||||
src.base := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_loadaddr_ref_reg(list,source,src.base);
|
||||
orgsrc := false;
|
||||
end
|
||||
@ -1879,7 +1747,7 @@ const
|
||||
((dest.index <> NR_NO) and
|
||||
((dest.offset + longint(len)) > high(smallint))) then
|
||||
begin
|
||||
dst.base := rgint.getregister(list,R_SUBWHOLE);
|
||||
dst.base := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_loadaddr_ref_reg(list,dest,dst.base);
|
||||
orgdst := false;
|
||||
end
|
||||
@ -1901,7 +1769,7 @@ const
|
||||
inc(src.offset,8);
|
||||
list.concat(taicpu.op_reg_reg_const(A_SUBI,src.base,src.base,8));
|
||||
list.concat(taicpu.op_reg_reg_const(A_SUBI,dst.base,dst.base,8));
|
||||
countreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
countreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_load_const_reg(list,OS_32,count,countreg);
|
||||
{ explicitely allocate R_0 since it can be used safely here }
|
||||
{ (for holding date that's being copied) }
|
||||
@ -1912,7 +1780,7 @@ const
|
||||
list.concat(taicpu.op_reg_ref(A_LFDU,NR_F0,src));
|
||||
list.concat(taicpu.op_reg_ref(A_STFDU,NR_F0,dst));
|
||||
a_jmp(list,A_BC,C_NE,0,lab);
|
||||
rgint.ungetregister(list,countreg);
|
||||
rg[R_INTREGISTER].ungetregister(list,countreg);
|
||||
a_reg_dealloc(list,NR_F0);
|
||||
len := len mod 8;
|
||||
end;
|
||||
@ -1954,7 +1822,7 @@ const
|
||||
inc(src.offset,4);
|
||||
list.concat(taicpu.op_reg_reg_const(A_SUBI,src.base,src.base,4));
|
||||
list.concat(taicpu.op_reg_reg_const(A_SUBI,dst.base,dst.base,4));
|
||||
countreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
countreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_load_const_reg(list,OS_32,count,countreg);
|
||||
{ explicitely allocate R_0 since it can be used safely here }
|
||||
{ (for holding date that's being copied) }
|
||||
@ -1965,7 +1833,7 @@ const
|
||||
list.concat(taicpu.op_reg_ref(A_LWZU,NR_R0,src));
|
||||
list.concat(taicpu.op_reg_ref(A_STWU,NR_R0,dst));
|
||||
a_jmp(list,A_BC,C_NE,0,lab);
|
||||
rgint.ungetregister(list,countreg);
|
||||
rg[R_INTREGISTER].ungetregister(list,countreg);
|
||||
a_reg_dealloc(list,NR_R0);
|
||||
len := len mod 4;
|
||||
end;
|
||||
@ -2009,9 +1877,9 @@ const
|
||||
reference_release(list,source);
|
||||
end
|
||||
else
|
||||
rgint.ungetregister(list,src.base);
|
||||
rg[R_INTREGISTER].ungetregister(list,src.base);
|
||||
if not orgdst then
|
||||
rgint.ungetregister(list,dst.base);
|
||||
rg[R_INTREGISTER].ungetregister(list,dst.base);
|
||||
if delsource then
|
||||
tg.ungetiftemp(list,source);
|
||||
end;
|
||||
@ -2153,13 +2021,13 @@ const
|
||||
{ otherwise it may be overwritten (and it's still used afterwards) }
|
||||
freeindex := false;
|
||||
if (ref.index >= first_int_imreg) and
|
||||
(supregset_in(rgint.unusedregs,getsupreg(ref.index))) then
|
||||
(supregset_in(rg[R_INTREGISTER].unusedregs,getsupreg(ref.index))) then
|
||||
begin
|
||||
rgint.getexplicitregister(list,ref.index);
|
||||
rg[R_INTREGISTER].getexplicitregister(list,ref.index);
|
||||
orgindex := ref.index;
|
||||
freeindex := true;
|
||||
end;
|
||||
tmpreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
if not assigned(ref.symbol) and
|
||||
(cardinal(ref.offset-low(smallint)) <=
|
||||
high(smallint)-low(smallint)) then
|
||||
@ -2176,7 +2044,7 @@ const
|
||||
end;
|
||||
ref.base := tmpreg;
|
||||
if freeindex then
|
||||
rgint.ungetregister(list,orgindex);
|
||||
rg[R_INTREGISTER].ungetregister(list,orgindex);
|
||||
end
|
||||
end
|
||||
else
|
||||
@ -2270,7 +2138,7 @@ const
|
||||
largeOffset:= (cardinal(ref.offset-low(smallint)) >
|
||||
high(smallint)-low(smallint));
|
||||
|
||||
tmpreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
tmpregUsed:= false;
|
||||
|
||||
if assigned(ref.symbol) then
|
||||
@ -2321,7 +2189,7 @@ const
|
||||
(cardinal(ref.offset-low(smallint)) >
|
||||
high(smallint)-low(smallint)) then
|
||||
begin
|
||||
tmpreg := rgint.getregister(list,R_SUBWHOLE);
|
||||
tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
reference_reset(tmpref);
|
||||
tmpref.symbol := ref.symbol;
|
||||
tmpref.offset := ref.offset;
|
||||
@ -2340,7 +2208,7 @@ const
|
||||
end;
|
||||
|
||||
if (tmpreg <> NR_NO) then
|
||||
rgint.ungetregister(list,tmpreg);
|
||||
rg[R_INTREGISTER].ungetregister(list,tmpreg);
|
||||
end;
|
||||
|
||||
|
||||
@ -2434,22 +2302,22 @@ const
|
||||
end
|
||||
else if ((value shr 32) = 0) then
|
||||
begin
|
||||
tmpreg := tcgppc(cg).rgint.getregister(list,R_SUBWHOLE);
|
||||
tmpreg := tcgppc(cg).rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
cg.a_load_const_reg(list,OS_32,cardinal(value),tmpreg);
|
||||
list.concat(taicpu.op_reg_reg_reg(ops[issub,2],
|
||||
regdst.reglo,regsrc.reglo,tmpreg));
|
||||
tcgppc(cg).rgint.ungetregister(list,tmpreg);
|
||||
tcgppc(cg).rg[R_INTREGISTER].ungetregister(list,tmpreg);
|
||||
list.concat(taicpu.op_reg_reg(ops[issub,3],
|
||||
regdst.reghi,regsrc.reghi));
|
||||
end
|
||||
else
|
||||
begin
|
||||
tmpreg64.reglo := tcgppc(cg).rgint.getregister(list,R_SUBWHOLE);
|
||||
tmpreg64.reghi := tcgppc(cg).rgint.getregister(list,R_SUBWHOLE);
|
||||
tmpreg64.reglo := tcgppc(cg).rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
tmpreg64.reghi := tcgppc(cg).rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
|
||||
a_load64_const_reg(list,value,tmpreg64);
|
||||
a_op64_reg_reg_reg(list,op,tmpreg64,regsrc,regdst);
|
||||
tcgppc(cg).rgint.ungetregister(list,tmpreg64.reglo);
|
||||
tcgppc(cg).rgint.ungetregister(list,tmpreg64.reghi);
|
||||
tcgppc(cg).rg[R_INTREGISTER].ungetregister(list,tmpreg64.reglo);
|
||||
tcgppc(cg).rg[R_INTREGISTER].ungetregister(list,tmpreg64.reghi);
|
||||
end
|
||||
end
|
||||
else
|
||||
@ -2471,7 +2339,10 @@ begin
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.145 2003-12-10 00:09:57 karoly
|
||||
Revision 1.146 2003-12-12 17:16:18 peter
|
||||
* rg[tregistertype] added in tcg
|
||||
|
||||
Revision 1.145 2003/12/10 00:09:57 karoly
|
||||
* fixed compilation with -dppc603
|
||||
|
||||
Revision 1.144 2003/12/09 20:39:43 jonas
|
||||
|
@ -176,17 +176,32 @@ unit rgobj;
|
||||
end;
|
||||
Preginfo=^TReginfo;
|
||||
|
||||
{ This is the base class used for a register allocator. }
|
||||
trgbase=class
|
||||
function getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;virtual;abstract;
|
||||
{# Get the register specified.}
|
||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;abstract;
|
||||
{# Get multiple registers specified.}
|
||||
procedure allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;abstract;
|
||||
{# Free multiple registers specified.}
|
||||
procedure deallocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;abstract;
|
||||
function uses_registers:boolean;virtual;abstract;
|
||||
{# Deallocate any kind of register }
|
||||
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;abstract;
|
||||
end;
|
||||
|
||||
|
||||
{#------------------------------------------------------------------
|
||||
|
||||
This class implements the abstract register allocator. It is used by the
|
||||
code generator to allocate and free registers which might be valid across
|
||||
nodes. It also contains utility routines related to registers.
|
||||
This class implements the default register allocator. It is used by the
|
||||
code generator to allocate and free registers which might be valid
|
||||
across nodes. It also contains utility routines related to registers.
|
||||
|
||||
Some of the methods in this class should be overriden
|
||||
by cpu-specific implementations.
|
||||
|
||||
--------------------------------------------------------------------}
|
||||
trgobj=class
|
||||
trgobj=class(trgbase)
|
||||
preserved_by_proc : tcpuregisterset;
|
||||
used_in_proc : tcpuregisterset;
|
||||
// is_reg_var : Tsuperregisterset; {old regvars}
|
||||
@ -201,20 +216,20 @@ unit rgobj;
|
||||
|
||||
{# Allocate a register. An internalerror will be generated if there is
|
||||
no more free registers which can be allocated.}
|
||||
function getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
||||
procedure add_constraints(reg:Tregister);virtual;
|
||||
function getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;virtual;
|
||||
{# Get the register specified.}
|
||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;
|
||||
{# Get multiple registers specified.}
|
||||
procedure allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);
|
||||
procedure allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;
|
||||
{# Free multiple registers specified.}
|
||||
procedure deallocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);
|
||||
function uses_registers:boolean;
|
||||
procedure deallocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;
|
||||
function uses_registers:boolean;virtual;
|
||||
{# Deallocate any kind of register }
|
||||
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
|
||||
procedure add_constraints(reg:Tregister);virtual;
|
||||
|
||||
{# Do the register allocation.}
|
||||
procedure do_register_allocation(list:Taasmoutput;headertai:tai);
|
||||
procedure do_register_allocation(list:Taasmoutput;headertai:tai);virtual;
|
||||
|
||||
{ procedure resetusableregisters;virtual;}
|
||||
|
||||
@ -615,17 +630,21 @@ implementation
|
||||
|
||||
|
||||
function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
|
||||
var p:Tsuperregister;
|
||||
r:Tregister;
|
||||
begin
|
||||
p:=getnewreg;
|
||||
supregset_exclude(unusedregs,p);
|
||||
r:=newreg(regtype,p,subreg);
|
||||
list.concat(Tai_regalloc.alloc(r));
|
||||
add_edges_used(p);
|
||||
add_constraints(r);
|
||||
result:=r;
|
||||
end;
|
||||
var
|
||||
p : Tsuperregister;
|
||||
r : Tregister;
|
||||
begin
|
||||
p:=getnewreg;
|
||||
supregset_exclude(unusedregs,p);
|
||||
if defaultsub=R_SUBNONE then
|
||||
r:=newreg(regtype,p,R_SUBNONE)
|
||||
else
|
||||
r:=newreg(regtype,p,subreg);
|
||||
list.concat(Tai_regalloc.alloc(r));
|
||||
add_edges_used(p);
|
||||
add_constraints(r);
|
||||
result:=r;
|
||||
end;
|
||||
|
||||
|
||||
function trgobj.uses_registers:boolean;
|
||||
@ -1818,7 +1837,10 @@ implementation
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.98 2003-12-04 23:27:32 peter
|
||||
Revision 1.99 2003-12-12 17:16:17 peter
|
||||
* rg[tregistertype] added in tcg
|
||||
|
||||
Revision 1.98 2003/12/04 23:27:32 peter
|
||||
* remove redundant calls to add_edge_used
|
||||
|
||||
Revision 1.97 2003/11/29 17:36:41 peter
|
||||
|
@ -36,27 +36,20 @@ unit cgx86;
|
||||
|
||||
type
|
||||
tcgx86 = class(tcg)
|
||||
rgint,
|
||||
rgmm : trgcpu;
|
||||
rgfpu : Trgx86fpu;
|
||||
procedure init_register_allocators;override;
|
||||
procedure done_register_allocators;override;
|
||||
|
||||
function getintregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
|
||||
procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
|
||||
procedure ungetregister(list:Taasmoutput;r:Tregister);override;
|
||||
procedure ungetreference(list:Taasmoutput;const r:Treference);override;
|
||||
procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
|
||||
procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
|
||||
function uses_registers(rt:Tregistertype):boolean;override;
|
||||
procedure add_move_instruction(instr:Taicpu);override;
|
||||
procedure dec_fpu_stack;
|
||||
procedure inc_fpu_stack;
|
||||
|
||||
procedure do_register_allocation(list:Taasmoutput;headertai:tai);override;
|
||||
|
||||
{ passing parameters, per default the parameter is pushed }
|
||||
{ nr gives the number of the parameter (enumerated from }
|
||||
{ left to right), this allows to move the parameter to }
|
||||
@ -176,123 +169,77 @@ unit cgx86;
|
||||
procedure Tcgx86.init_register_allocators;
|
||||
begin
|
||||
if cs_create_pic in aktmoduleswitches then
|
||||
rgint:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP,RS_EBX])
|
||||
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP,RS_EBX])
|
||||
else
|
||||
rgint:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
|
||||
rgmm:=trgcpu.create(R_MMREGISTER,R_SUBNONE,[RS_MM0,RS_MM1,RS_MM2,RS_MM3,RS_MM4,RS_MM5,RS_MM6,RS_MM7],first_sse_imreg,[]);
|
||||
rg[R_INTREGISTER]:=trgcpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_EAX,RS_EDX,RS_ECX,RS_EBX,RS_ESI,RS_EDI],first_int_imreg,[RS_EBP]);
|
||||
rg[R_MMREGISTER]:=trgcpu.create(R_MMREGISTER,R_SUBNONE,[RS_MM0,RS_MM1,RS_MM2,RS_MM3,RS_MM4,RS_MM5,RS_MM6,RS_MM7],first_sse_imreg,[]);
|
||||
rgfpu:=Trgx86fpu.create;
|
||||
end;
|
||||
|
||||
|
||||
procedure Tcgx86.done_register_allocators;
|
||||
begin
|
||||
rgint.free;
|
||||
rgmm.free;
|
||||
rg[R_INTREGISTER].free;
|
||||
rg[R_INTREGISTER]:=nil;
|
||||
rg[R_MMREGISTER].free;
|
||||
rg[R_MMREGISTER]:=nil;
|
||||
rgfpu.free;
|
||||
end;
|
||||
|
||||
|
||||
function Tcgx86.getintregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=rgint.getregister(list,cgsize2subreg(size));
|
||||
end;
|
||||
|
||||
|
||||
function Tcgx86.getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=trgx86fpu(rgfpu).getregisterfpu(list);
|
||||
end;
|
||||
|
||||
|
||||
function Tcgx86.getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;
|
||||
begin
|
||||
result:=rgmm.getregister(list,R_SUBNONE);
|
||||
result:=rgfpu.getregisterfpu(list);
|
||||
end;
|
||||
|
||||
|
||||
procedure Tcgx86.getexplicitregister(list:Taasmoutput;r:Tregister);
|
||||
begin
|
||||
case getregtype(r) of
|
||||
R_INTREGISTER :
|
||||
rgint.getexplicitregister(list,r);
|
||||
R_SSEREGISTER :
|
||||
rgmm.getexplicitregister(list,r);
|
||||
else
|
||||
internalerror(200310091);
|
||||
end;
|
||||
if getregtype(r)=R_FPUREGISTER then
|
||||
internalerror(2003121210)
|
||||
else
|
||||
inherited getexplicitregister(list,r);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgx86.ungetregister(list:Taasmoutput;r:Tregister);
|
||||
begin
|
||||
case getregtype(r) of
|
||||
R_INTREGISTER :
|
||||
rgint.ungetregister(list,r);
|
||||
R_FPUREGISTER :
|
||||
rgfpu.ungetregisterfpu(list,r);
|
||||
R_SSEREGISTER :
|
||||
rgmm.ungetregister(list,r);
|
||||
else
|
||||
internalerror(200310091);
|
||||
end;
|
||||
if getregtype(r)=R_FPUREGISTER then
|
||||
rgfpu.ungetregisterfpu(list,r)
|
||||
else
|
||||
inherited ungetregister(list,r);
|
||||
end;
|
||||
|
||||
|
||||
procedure tcgx86.ungetreference(list:Taasmoutput;const r:Treference);
|
||||
begin
|
||||
if r.base<>NR_NO then
|
||||
rgint.ungetregister(list,r.base);
|
||||
ungetregister(list,r.base);
|
||||
if r.index<>NR_NO then
|
||||
rgint.ungetregister(list,r.index);
|
||||
ungetregister(list,r.index);
|
||||
end;
|
||||
|
||||
|
||||
procedure Tcgx86.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
|
||||
begin
|
||||
case rt of
|
||||
R_INTREGISTER :
|
||||
rgint.allocexplicitregisters(list,r);
|
||||
R_SSEREGISTER :
|
||||
rgmm.allocexplicitregisters(list,r);
|
||||
R_FPUREGISTER :
|
||||
else
|
||||
internalerror(200310092);
|
||||
end;
|
||||
if rt<>R_FPUREGISTER then
|
||||
inherited allocexplicitregisters(list,rt,r);
|
||||
end;
|
||||
|
||||
|
||||
procedure Tcgx86.deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
|
||||
begin
|
||||
case rt of
|
||||
R_INTREGISTER :
|
||||
rgint.deallocexplicitregisters(list,r);
|
||||
R_SSEREGISTER :
|
||||
rgmm.deallocexplicitregisters(list,r);
|
||||
R_FPUREGISTER :
|
||||
else
|
||||
internalerror(200310093);
|
||||
end;
|
||||
if rt<>R_FPUREGISTER then
|
||||
inherited deallocexplicitregisters(list,rt,r);
|
||||
end;
|
||||
|
||||
|
||||
function Tcgx86.uses_registers(rt:Tregistertype):boolean;
|
||||
begin
|
||||
case rt of
|
||||
R_INTREGISTER :
|
||||
result:=rgint.uses_registers;
|
||||
R_SSEREGISTER :
|
||||
result:=rgmm.uses_registers;
|
||||
R_FPUREGISTER :
|
||||
result:=false;
|
||||
else
|
||||
internalerror(200310094);
|
||||
end;
|
||||
end;
|
||||
|
||||
|
||||
procedure Tcgx86.add_move_instruction(instr:Taicpu);
|
||||
begin
|
||||
rgint.add_move_instruction(instr);
|
||||
if rt=R_FPUREGISTER then
|
||||
result:=false
|
||||
else
|
||||
result:=inherited uses_registers(rt);
|
||||
end;
|
||||
|
||||
|
||||
@ -308,20 +255,6 @@ unit cgx86;
|
||||
end;
|
||||
|
||||
|
||||
procedure Tcgx86.do_register_allocation(list:Taasmoutput;headertai:tai);
|
||||
|
||||
begin
|
||||
{ Int }
|
||||
rgint.check_unreleasedregs;
|
||||
rgint.do_register_allocation(list,headertai);
|
||||
rgint.translate_registers(list);
|
||||
{ SSE }
|
||||
rgmm.check_unreleasedregs;
|
||||
rgmm.do_register_allocation(list,headertai);
|
||||
rgmm.translate_registers(list);
|
||||
end;
|
||||
|
||||
|
||||
{****************************************************************************
|
||||
This is private property, keep out! :)
|
||||
****************************************************************************}
|
||||
@ -706,7 +639,7 @@ unit cgx86;
|
||||
instr:=taicpu.op_reg_reg(op,s,reg1,reg2);
|
||||
{Notify the register allocator that we have written a move instruction so
|
||||
it can try to eliminate it.}
|
||||
Tcgx86(cg).rgint.add_move_instruction(instr);
|
||||
add_move_instruction(instr);
|
||||
list.concat(instr);
|
||||
end;
|
||||
|
||||
@ -1513,7 +1446,7 @@ unit cgx86;
|
||||
list.concat(Tai_section.Create(sec_code));
|
||||
list.concat(Taicpu.Op_sym_ofs_reg(A_MOV,S_L,pl,0,NR_EDX));
|
||||
a_call_name(list,target_info.Cprefix+mcountprefix+'mcount');
|
||||
include(rgint.used_in_proc,RS_EDX);
|
||||
include(rg[R_INTREGISTER].used_in_proc,RS_EDX);
|
||||
end;
|
||||
|
||||
system_i386_go32v2,system_i386_watcom:
|
||||
@ -1575,7 +1508,7 @@ unit cgx86;
|
||||
|
||||
begin
|
||||
list.concat(tai_regalloc.alloc(NR_EBP));
|
||||
include(rgint.preserved_by_proc,RS_EBP);
|
||||
include(rg[R_INTREGISTER].preserved_by_proc,RS_EBP);
|
||||
list.concat(Taicpu.op_reg(A_PUSH,S_L,NR_EBP));
|
||||
list.concat(Taicpu.op_reg_reg(A_MOV,S_L,NR_ESP,NR_EBP));
|
||||
if localsize>0 then
|
||||
@ -1633,36 +1566,36 @@ unit cgx86;
|
||||
begin
|
||||
{ Get temp }
|
||||
size:=0;
|
||||
if RS_EBX in rgint.used_in_proc then
|
||||
if RS_EBX in rg[R_INTREGISTER].used_in_proc then
|
||||
inc(size,POINTER_SIZE);
|
||||
if RS_ESI in rgint.used_in_proc then
|
||||
if RS_ESI in rg[R_INTREGISTER].used_in_proc then
|
||||
inc(size,POINTER_SIZE);
|
||||
if RS_EDI in rgint.used_in_proc then
|
||||
if RS_EDI in rg[R_INTREGISTER].used_in_proc then
|
||||
inc(size,POINTER_SIZE);
|
||||
if size>0 then
|
||||
begin
|
||||
tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref);
|
||||
{ Copy registers to temp }
|
||||
href:=current_procinfo.save_regs_ref;
|
||||
if RS_EBX in rgint.used_in_proc then
|
||||
if RS_EBX in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EBX,href);
|
||||
inc(href.offset,POINTER_SIZE);
|
||||
end;
|
||||
if RS_ESI in rgint.used_in_proc then
|
||||
if RS_ESI in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_ESI,href);
|
||||
inc(href.offset,POINTER_SIZE);
|
||||
end;
|
||||
if RS_EDI in rgint.used_in_proc then
|
||||
if RS_EDI in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EDI,href);
|
||||
inc(href.offset,POINTER_SIZE);
|
||||
end;
|
||||
end;
|
||||
include(rgint.preserved_by_proc,RS_EBX);
|
||||
include(rgint.preserved_by_proc,RS_ESI);
|
||||
include(rgint.preserved_by_proc,RS_EDI);
|
||||
include(rg[R_INTREGISTER].preserved_by_proc,RS_EBX);
|
||||
include(rg[R_INTREGISTER].preserved_by_proc,RS_ESI);
|
||||
include(rg[R_INTREGISTER].preserved_by_proc,RS_EDI);
|
||||
end;
|
||||
|
||||
|
||||
@ -1672,17 +1605,17 @@ unit cgx86;
|
||||
begin
|
||||
{ Copy registers from temp }
|
||||
href:=current_procinfo.save_regs_ref;
|
||||
if RS_EBX in rgint.used_in_proc then
|
||||
if RS_EBX in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EBX);
|
||||
inc(href.offset,POINTER_SIZE);
|
||||
end;
|
||||
if RS_ESI in rgint.used_in_proc then
|
||||
if RS_ESI in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_ESI);
|
||||
inc(href.offset,POINTER_SIZE);
|
||||
end;
|
||||
if RS_EDI in rgint.used_in_proc then
|
||||
if RS_EDI in rg[R_INTREGISTER].used_in_proc then
|
||||
begin
|
||||
a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EDI);
|
||||
inc(href.offset,POINTER_SIZE);
|
||||
@ -1751,7 +1684,10 @@ unit cgx86;
|
||||
end.
|
||||
{
|
||||
$Log$
|
||||
Revision 1.89 2003-12-06 01:15:23 florian
|
||||
Revision 1.90 2003-12-12 17:16:18 peter
|
||||
* rg[tregistertype] added in tcg
|
||||
|
||||
Revision 1.89 2003/12/06 01:15:23 florian
|
||||
* reverted Peter's alloctemp patch; hopefully properly
|
||||
|
||||
Revision 1.88 2003/12/03 23:13:20 peter
|
||||
|
Loading…
Reference in New Issue
Block a user