* rg[tregistertype] added in tcg

This commit is contained in:
peter 2003-12-12 17:16:17 +00:00
parent 8b4a122d49
commit bce5a1e252
4 changed files with 289 additions and 351 deletions

View File

@ -59,7 +59,9 @@ unit cgobj;
sould be @link(tcg64f32) and not @var(tcg). sould be @link(tcg64f32) and not @var(tcg).
} }
tcg = class tcg = class
public
alignment : talignment; alignment : talignment;
rg : array[tregistertype] of trgobj;
t_times:cardinal; t_times:cardinal;
{************************************************} {************************************************}
{ basic routines } { basic routines }
@ -71,28 +73,28 @@ unit cgobj;
procedure done_register_allocators;virtual;abstract; procedure done_register_allocators;virtual;abstract;
{# Gets a register suitable to do integer operations on.} {# 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.} {# Gets a register suitable to do integer operations on.}
function getaddressregister(list:Taasmoutput):Tregister;virtual; function getaddressregister(list:Taasmoutput):Tregister;virtual;
function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract; function getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;
function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract; function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;
function getflagregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract; function getflagregister(list:Taasmoutput;size:Tcgsize):Tregister;virtual;abstract;
{Does the generic cg need SIMD registers, like getmmxregister? Or should {Does the generic cg need SIMD registers, like getmmxregister? Or should
the cpu specific child cg object have such a method?} 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 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.} {# Get a specific register.}
procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;abstract; procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;
{# Get multiple registers specified.} {# 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.} {# 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; function makeregsize(reg:Tregister;size:Tcgsize):Tregister;
@ -550,14 +552,13 @@ implementation
******************************************************************************} ******************************************************************************}
constructor tcg.create; constructor tcg.create;
begin begin
end; end;
function Tcg.makeregsize(reg:Tregister;size:Tcgsize):Tregister; function Tcg.makeregsize(reg:Tregister;size:Tcgsize):Tregister;
var
var subreg:Tsubregister; subreg:Tsubregister;
begin begin
subreg:=cgsize2subreg(size); subreg:=cgsize2subreg(size);
result:=reg; result:=reg;
@ -565,9 +566,60 @@ implementation
end; 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; function tcg.getaddressregister(list:Taasmoutput):Tregister;
begin 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; end;
@ -578,6 +630,61 @@ implementation
end; 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); procedure tcg.a_reg_alloc(list : taasmoutput;r : tregister);
begin begin
list.concat(tai_regalloc.alloc(r)); list.concat(tai_regalloc.alloc(r));
@ -619,11 +726,10 @@ implementation
end; end;
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 var
hr : tregister; hr : tregister;
begin begin
hr:=getintregister(list,size); hr:=getintregister(list,size);
a_load_const_reg(list,size,a,hr); a_load_const_reg(list,size,a,hr);
@ -1835,7 +1941,10 @@ finalization
end. end.
{ {
$Log$ $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 + allocate volatile registers around calls to procedures declared with
"saveregisters" on non-x86 processors "saveregisters" on non-x86 processors

View File

@ -34,24 +34,10 @@ unit cgcpu;
type type
tcgppc = class(tcg) tcgppc = class(tcg)
rgint,
rgflags,
rgmm,
rgfpu : trgcpu;
procedure init_register_allocators;override; procedure init_register_allocators;override;
procedure done_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 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 } { passing parameters, per default the parameter is pushed }
{ nr gives the number of the parameter (enumerated from } { nr gives the number of the parameter (enumerated from }
@ -180,155 +166,37 @@ const
procedure tcgppc.init_register_allocators; procedure tcgppc.init_register_allocators;
begin 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_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_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_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_R21,RS_R20,RS_R19,RS_R18,RS_R17,RS_R16,RS_R15,
RS_R14,RS_R13],first_int_imreg,[]); 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_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_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_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,[]); RS_F17,RS_F16,RS_F15,RS_F14],first_fpu_imreg,[]);
{$warning FIX ME} {$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,[]); [RS_M0,RS_M1,RS_M2],first_mm_imreg,[]);
end; end;
procedure tcgppc.done_register_allocators; procedure tcgppc.done_register_allocators;
begin begin
rgint.free; rg[R_INTREGISTER].free;
rgmm.free; rg[R_FPUREGISTER].free;
rgfpu.free; rg[R_MMREGISTER].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;
end; end;
procedure tcgppc.ungetreference(list:Taasmoutput;const r:Treference); procedure tcgppc.ungetreference(list:Taasmoutput;const r:Treference);
begin begin
if r.base<>NR_NO then if r.base<>NR_NO then
rgint.ungetregister(list,r.base); ungetregister(list,r.base);
if r.index<>NR_NO then if r.index<>NR_NO then
rgint.ungetregister(list,r.index); 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);
end; end;
@ -367,10 +235,10 @@ const
reference_reset(ref); reference_reset(ref);
ref.base:=locpara.reference.index; ref.base:=locpara.reference.index;
ref.offset:=locpara.reference.offset; 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_ref_reg(list,size,size,r,tmpreg);
a_load_reg_ref(list,size,size,tmpreg,ref); a_load_reg_ref(list,size,size,tmpreg,ref);
rgint.ungetregister(list,tmpreg); rg[R_INTREGISTER].ungetregister(list,tmpreg);
end; end;
LOC_FPUREGISTER,LOC_CFPUREGISTER: LOC_FPUREGISTER,LOC_CFPUREGISTER:
case size of case size of
@ -399,10 +267,10 @@ const
reference_reset(ref); reference_reset(ref);
ref.base := locpara.reference.index; ref.base := locpara.reference.index;
ref.offset := locpara.reference.offset; 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_loadaddr_ref_reg(list,r,tmpreg);
a_load_reg_ref(list,OS_ADDR,OS_ADDR,tmpreg,ref); a_load_reg_ref(list,OS_ADDR,OS_ADDR,tmpreg,ref);
rgint.ungetregister(list,tmpreg); rg[R_INTREGISTER].ungetregister(list,tmpreg);
end; end;
else else
internalerror(2002080701); internalerror(2002080701);
@ -438,14 +306,14 @@ const
{Generate instruction to load the procedure address from {Generate instruction to load the procedure address from
the transition vector.} the transition vector.}
//TODO: Support cross-TOC calls. //TODO: Support cross-TOC calls.
tmpreg := rgint.getregister(list,R_SUBWHOLE); tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
reference_reset(tmpref); reference_reset(tmpref);
tmpref.offset := 0; tmpref.offset := 0;
//tmpref.symaddr := refs_full; //tmpref.symaddr := refs_full;
tmpref.base:= reg; tmpref.base:= reg;
list.concat(taicpu.op_reg_ref(A_LWZ,tmpreg,tmpref)); list.concat(taicpu.op_reg_ref(A_LWZ,tmpreg,tmpref));
list.concat(taicpu.op_reg(A_MTCTR,tmpreg)); list.concat(taicpu.op_reg(A_MTCTR,tmpreg));
rgint.ungetregister(list,tmpreg); rg[R_INTREGISTER].ungetregister(list,tmpreg);
end end
else else
list.concat(taicpu.op_reg(A_MTCTR,reg)); list.concat(taicpu.op_reg(A_MTCTR,reg));
@ -506,7 +374,7 @@ const
op := storeinstr[tcgsize2unsigned[tosize],ref2.index<>NR_NO,false]; op := storeinstr[tcgsize2unsigned[tosize],ref2.index<>NR_NO,false];
a_load_store(list,op,reg,ref2); a_load_store(list,op,reg,ref2);
if freereg then if freereg then
rgint.ungetregister(list,ref2.base); rg[R_INTREGISTER].ungetregister(list,ref2.base);
End; End;
@ -544,7 +412,7 @@ const
op := loadinstr[fromsize,ref2.index<>NR_NO,false]; op := loadinstr[fromsize,ref2.index<>NR_NO,false];
a_load_store(list,op,reg,ref2); a_load_store(list,op,reg,ref2);
if freereg then if freereg then
rgint.ungetregister(list,ref2.base); rg[R_INTREGISTER].ungetregister(list,ref2.base);
{ sign extend shortint if necessary, since there is no } { sign extend shortint if necessary, since there is no }
{ load instruction that does that automatically (JM) } { load instruction that does that automatically (JM) }
if fromsize = OS_S8 then if fromsize = OS_S8 then
@ -579,7 +447,7 @@ const
else internalerror(2002090901); else internalerror(2002090901);
end; end;
list.concat(instr); list.concat(instr);
rgint.add_move_instruction(instr); rg[R_INTREGISTER].add_move_instruction(instr);
end; end;
end; end;
@ -619,7 +487,7 @@ const
op := fpuloadinstr[size,ref2.index <> NR_NO,false]; op := fpuloadinstr[size,ref2.index <> NR_NO,false];
a_load_store(list,op,reg,ref2); a_load_store(list,op,reg,ref2);
if freereg then if freereg then
rgint.ungetregister(list,ref2.base); rg[R_INTREGISTER].ungetregister(list,ref2.base);
end; end;
@ -643,7 +511,7 @@ const
op := fpustoreinstr[size,ref2.index <> NR_NO,false]; op := fpustoreinstr[size,ref2.index <> NR_NO,false];
a_load_store(list,op,reg,ref2); a_load_store(list,op,reg,ref2);
if freereg then if freereg then
rgint.ungetregister(list,ref2.base); rg[R_INTREGISTER].ungetregister(list,ref2.base);
end; end;
@ -799,11 +667,11 @@ const
if gotrlwi and if gotrlwi and
(src = dst) then (src = dst) then
begin 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_const(A_LI,scratchreg,-1));
list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,dst, list.concat(taicpu.op_reg_reg_const_const_const(A_RLWIMI,dst,
scratchreg,0,l1,l2)); scratchreg,0,l1,l2));
rgint.ungetregister(list,scratchreg); rg[R_INTREGISTER].ungetregister(list,scratchreg);
end end
else else
do_lo_hi; do_lo_hi;
@ -833,10 +701,10 @@ const
{ perform the operation } { perform the operation }
if useReg then if useReg then
begin 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_load_const_reg(list,OS_32,a,scratchreg);
a_op_reg_reg_reg(list,op,OS_32,scratchreg,src,dst); a_op_reg_reg_reg(list,op,OS_32,scratchreg,src,dst);
rgint.ungetregister(list,scratchreg); rg[R_INTREGISTER].ungetregister(list,scratchreg);
end; end;
end; end;
@ -881,20 +749,20 @@ const
list.concat(taicpu.op_reg_reg_const(A_CMPWI,NR_CR0,reg,longint(a))) list.concat(taicpu.op_reg_reg_const(A_CMPWI,NR_CR0,reg,longint(a)))
else else
begin 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); a_load_const_reg(list,OS_32,a,scratch_register);
list.concat(taicpu.op_reg_reg_reg(A_CMPW,NR_CR0,reg,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 end
else else
if (a <= $ffff) then if (a <= $ffff) then
list.concat(taicpu.op_reg_reg_const(A_CMPLWI,NR_CR0,reg,a)) list.concat(taicpu.op_reg_reg_const(A_CMPLWI,NR_CR0,reg,a))
else else
begin 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); a_load_const_reg(list,OS_32,a,scratch_register);
list.concat(taicpu.op_reg_reg_reg(A_CMPLW,NR_CR0,reg,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; end;
a_jmp(list,A_BC,TOpCmp2AsmCond[cmp_op],0,l); a_jmp(list,A_BC,TOpCmp2AsmCond[cmp_op],0,l);
end; end;
@ -1088,7 +956,7 @@ const
{ FIXME: has to be R_F8 instad of R_F14 for SYSV abi } { FIXME: has to be R_F8 instad of R_F14 for SYSV abi }
for regcounter:=RS_F14 to RS_F31 do for regcounter:=RS_F14 to RS_F31 do
begin begin
if regcounter in rgfpu.used_in_proc then if regcounter in rg[R_FPUREGISTER].used_in_proc then
begin begin
usesfpr:= true; usesfpr:= true;
firstregfpu:=regcounter; firstregfpu:=regcounter;
@ -1100,7 +968,7 @@ const
if not (po_assembler in current_procinfo.procdef.procoptions) then if not (po_assembler in current_procinfo.procdef.procoptions) then
for regcounter2:=RS_R13 to RS_R31 do for regcounter2:=RS_R13 to RS_R31 do
begin begin
if regcounter2 in rgint.used_in_proc then if regcounter2 in rg[R_INTREGISTER].used_in_proc then
begin begin
usesgpr:=true; usesgpr:=true;
firstreggpr:=regcounter2; firstreggpr:=regcounter2;
@ -1183,7 +1051,7 @@ const
reference_reset_base(href,NR_R12,-8); reference_reset_base(href,NR_R12,-8);
for regcounter:=firstregfpu to RS_F31 do for regcounter:=firstregfpu to RS_F31 do
begin begin
if regcounter in rgfpu.used_in_proc then if regcounter in rg[R_FPUREGISTER].used_in_proc then
begin begin
a_loadfpu_reg_ref(list,OS_F64,newreg(R_FPUREGISTER,regcounter,R_SUBNONE),href); a_loadfpu_reg_ref(list,OS_F64,newreg(R_FPUREGISTER,regcounter,R_SUBNONE),href);
dec(href.offset,8); dec(href.offset,8);
@ -1209,7 +1077,7 @@ const
reference_reset_base(href,NR_R12,-4); reference_reset_base(href,NR_R12,-4);
for regcounter2:=RS_R13 to RS_R31 do for regcounter2:=RS_R13 to RS_R31 do
begin begin
if regcounter2 in rgint.used_in_proc then if regcounter2 in rg[R_INTREGISTER].used_in_proc then
begin begin
usesgpr:=true; usesgpr:=true;
a_load_reg_ref(list,OS_INT,OS_INT,newreg(R_INTREGISTER,regcounter2,R_SUBNONE),href); a_load_reg_ref(list,OS_INT,OS_INT,newreg(R_INTREGISTER,regcounter2,R_SUBNONE),href);
@ -1306,7 +1174,7 @@ const
if not (po_assembler in current_procinfo.procdef.procoptions) then if not (po_assembler in current_procinfo.procdef.procoptions) then
for regcounter:=RS_F14 to RS_F31 do for regcounter:=RS_F14 to RS_F31 do
begin begin
if regcounter in rgfpu.used_in_proc then if regcounter in rg[R_FPUREGISTER].used_in_proc then
begin begin
usesfpr:=true; usesfpr:=true;
firstregfpu:=regcounter; firstregfpu:=regcounter;
@ -1318,7 +1186,7 @@ const
if not (po_assembler in current_procinfo.procdef.procoptions) then if not (po_assembler in current_procinfo.procdef.procoptions) then
for regcounter2:=RS_R13 to RS_R31 do for regcounter2:=RS_R13 to RS_R31 do
begin begin
if regcounter2 in rgint.used_in_proc then if regcounter2 in rg[R_INTREGISTER].used_in_proc then
begin begin
usesgpr:=true; usesgpr:=true;
firstreggpr:=regcounter2; firstreggpr:=regcounter2;
@ -1339,7 +1207,7 @@ const
reference_reset_base(href,NR_R12,-8); reference_reset_base(href,NR_R12,-8);
for regcounter := firstregfpu to RS_F31 do for regcounter := firstregfpu to RS_F31 do
begin begin
if regcounter in rgfpu.used_in_proc then if regcounter in rg[R_FPUREGISTER].used_in_proc then
begin begin
a_loadfpu_ref_reg(list,OS_F64,href,newreg(R_FPUREGISTER,regcounter,R_SUBNONE)); a_loadfpu_ref_reg(list,OS_F64,href,newreg(R_FPUREGISTER,regcounter,R_SUBNONE));
dec(href.offset,8); dec(href.offset,8);
@ -1352,7 +1220,7 @@ const
for regcounter2:=RS_R13 to RS_R31 do for regcounter2:=RS_R13 to RS_R31 do
begin begin
if regcounter2 in rgint.used_in_proc then if regcounter2 in rg[R_INTREGISTER].used_in_proc then
begin begin
usesgpr:=true; usesgpr:=true;
a_load_ref_reg(list,OS_INT,OS_INT,href,newreg(R_INTREGISTER,regcounter2,R_SUBNONE)); 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 if not (po_assembler in current_procinfo.procdef.procoptions) then
for regcounter:=RS_F14 to RS_F31 do for regcounter:=RS_F14 to RS_F31 do
begin begin
if regcounter in rgfpu.used_in_proc then if regcounter in rg[R_FPUREGISTER].used_in_proc then
begin begin
usesfpr:=true; usesfpr:=true;
firstregfpu:=regcounter; firstregfpu:=regcounter;
@ -1448,7 +1316,7 @@ const
if not (po_assembler in current_procinfo.procdef.procoptions) then if not (po_assembler in current_procinfo.procdef.procoptions) then
for regcounter2:=RS_R13 to RS_R31 do for regcounter2:=RS_R13 to RS_R31 do
begin begin
if regcounter2 in rgint.used_in_proc then if regcounter2 in rg[R_INTREGISTER].used_in_proc then
begin begin
usesgpr:=true; usesgpr:=true;
firstreggpr:=regcounter2; firstreggpr:=regcounter2;
@ -1506,7 +1374,7 @@ const
if not (po_assembler in current_procinfo.procdef.procoptions) then if not (po_assembler in current_procinfo.procdef.procoptions) then
for regcounter:=RS_F14 to RS_F31 do for regcounter:=RS_F14 to RS_F31 do
begin begin
if regcounter in rgfpu.used_in_proc then if regcounter in rg[R_FPUREGISTER].used_in_proc then
begin begin
usesfpr:=true; usesfpr:=true;
firstregfpu:=regcounter; firstregfpu:=regcounter;
@ -1518,7 +1386,7 @@ const
if not (po_assembler in current_procinfo.procdef.procoptions) then if not (po_assembler in current_procinfo.procdef.procoptions) then
for regcounter2:=RS_R13 to RS_R31 do for regcounter2:=RS_R13 to RS_R31 do
begin begin
if regcounter2 in rgint.used_in_proc then if regcounter2 in rg[R_INTREGISTER].used_in_proc then
begin begin
usesgpr:=true; usesgpr:=true;
firstreggpr:=regcounter2; firstreggpr:=regcounter2;
@ -1761,7 +1629,7 @@ const
ref2.base,tmpref)); ref2.base,tmpref));
if freereg then if freereg then
begin begin
rgint.ungetregister(list,ref2.base); rg[R_INTREGISTER].ungetregister(list,ref2.base);
freereg := false; freereg := false;
end; end;
end end
@ -1787,7 +1655,7 @@ const
(r <> ref2.base) then (r <> ref2.base) then
list.concat(taicpu.op_reg_reg(A_MR,r,ref2.base)); list.concat(taicpu.op_reg_reg(A_MR,r,ref2.base));
if freereg then if freereg then
rgint.ungetregister(list,ref2.base); rg[R_INTREGISTER].ungetregister(list,ref2.base);
end; end;
{ ************* concatcopy ************ } { ************* concatcopy ************ }
@ -1853,7 +1721,7 @@ const
{ load the address of source into src.base } { load the address of source into src.base }
if loadref then if loadref then
begin 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); a_load_ref_reg(list,OS_32,OS_32,source,src.base);
orgsrc := false; orgsrc := false;
end end
@ -1862,7 +1730,7 @@ const
((source.index <> NR_NO) and ((source.index <> NR_NO) and
((source.offset + longint(len)) > high(smallint))) then ((source.offset + longint(len)) > high(smallint))) then
begin 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); a_loadaddr_ref_reg(list,source,src.base);
orgsrc := false; orgsrc := false;
end end
@ -1879,7 +1747,7 @@ const
((dest.index <> NR_NO) and ((dest.index <> NR_NO) and
((dest.offset + longint(len)) > high(smallint))) then ((dest.offset + longint(len)) > high(smallint))) then
begin 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); a_loadaddr_ref_reg(list,dest,dst.base);
orgdst := false; orgdst := false;
end end
@ -1901,7 +1769,7 @@ const
inc(src.offset,8); 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,src.base,src.base,8));
list.concat(taicpu.op_reg_reg_const(A_SUBI,dst.base,dst.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); a_load_const_reg(list,OS_32,count,countreg);
{ explicitely allocate R_0 since it can be used safely here } { explicitely allocate R_0 since it can be used safely here }
{ (for holding date that's being copied) } { (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_LFDU,NR_F0,src));
list.concat(taicpu.op_reg_ref(A_STFDU,NR_F0,dst)); list.concat(taicpu.op_reg_ref(A_STFDU,NR_F0,dst));
a_jmp(list,A_BC,C_NE,0,lab); 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); a_reg_dealloc(list,NR_F0);
len := len mod 8; len := len mod 8;
end; end;
@ -1954,7 +1822,7 @@ const
inc(src.offset,4); 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,src.base,src.base,4));
list.concat(taicpu.op_reg_reg_const(A_SUBI,dst.base,dst.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); a_load_const_reg(list,OS_32,count,countreg);
{ explicitely allocate R_0 since it can be used safely here } { explicitely allocate R_0 since it can be used safely here }
{ (for holding date that's being copied) } { (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_LWZU,NR_R0,src));
list.concat(taicpu.op_reg_ref(A_STWU,NR_R0,dst)); list.concat(taicpu.op_reg_ref(A_STWU,NR_R0,dst));
a_jmp(list,A_BC,C_NE,0,lab); 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); a_reg_dealloc(list,NR_R0);
len := len mod 4; len := len mod 4;
end; end;
@ -2009,9 +1877,9 @@ const
reference_release(list,source); reference_release(list,source);
end end
else else
rgint.ungetregister(list,src.base); rg[R_INTREGISTER].ungetregister(list,src.base);
if not orgdst then if not orgdst then
rgint.ungetregister(list,dst.base); rg[R_INTREGISTER].ungetregister(list,dst.base);
if delsource then if delsource then
tg.ungetiftemp(list,source); tg.ungetiftemp(list,source);
end; end;
@ -2153,13 +2021,13 @@ const
{ otherwise it may be overwritten (and it's still used afterwards) } { otherwise it may be overwritten (and it's still used afterwards) }
freeindex := false; freeindex := false;
if (ref.index >= first_int_imreg) and 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 begin
rgint.getexplicitregister(list,ref.index); rg[R_INTREGISTER].getexplicitregister(list,ref.index);
orgindex := ref.index; orgindex := ref.index;
freeindex := true; freeindex := true;
end; end;
tmpreg := rgint.getregister(list,R_SUBWHOLE); tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
if not assigned(ref.symbol) and if not assigned(ref.symbol) and
(cardinal(ref.offset-low(smallint)) <= (cardinal(ref.offset-low(smallint)) <=
high(smallint)-low(smallint)) then high(smallint)-low(smallint)) then
@ -2176,7 +2044,7 @@ const
end; end;
ref.base := tmpreg; ref.base := tmpreg;
if freeindex then if freeindex then
rgint.ungetregister(list,orgindex); rg[R_INTREGISTER].ungetregister(list,orgindex);
end end
end end
else else
@ -2270,7 +2138,7 @@ const
largeOffset:= (cardinal(ref.offset-low(smallint)) > largeOffset:= (cardinal(ref.offset-low(smallint)) >
high(smallint)-low(smallint)); high(smallint)-low(smallint));
tmpreg := rgint.getregister(list,R_SUBWHOLE); tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
tmpregUsed:= false; tmpregUsed:= false;
if assigned(ref.symbol) then if assigned(ref.symbol) then
@ -2321,7 +2189,7 @@ const
(cardinal(ref.offset-low(smallint)) > (cardinal(ref.offset-low(smallint)) >
high(smallint)-low(smallint)) then high(smallint)-low(smallint)) then
begin begin
tmpreg := rgint.getregister(list,R_SUBWHOLE); tmpreg := rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
reference_reset(tmpref); reference_reset(tmpref);
tmpref.symbol := ref.symbol; tmpref.symbol := ref.symbol;
tmpref.offset := ref.offset; tmpref.offset := ref.offset;
@ -2340,7 +2208,7 @@ const
end; end;
if (tmpreg <> NR_NO) then if (tmpreg <> NR_NO) then
rgint.ungetregister(list,tmpreg); rg[R_INTREGISTER].ungetregister(list,tmpreg);
end; end;
@ -2434,22 +2302,22 @@ const
end end
else if ((value shr 32) = 0) then else if ((value shr 32) = 0) then
begin 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); cg.a_load_const_reg(list,OS_32,cardinal(value),tmpreg);
list.concat(taicpu.op_reg_reg_reg(ops[issub,2], list.concat(taicpu.op_reg_reg_reg(ops[issub,2],
regdst.reglo,regsrc.reglo,tmpreg)); 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], list.concat(taicpu.op_reg_reg(ops[issub,3],
regdst.reghi,regsrc.reghi)); regdst.reghi,regsrc.reghi));
end end
else else
begin begin
tmpreg64.reglo := tcgppc(cg).rgint.getregister(list,R_SUBWHOLE); tmpreg64.reglo := tcgppc(cg).rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
tmpreg64.reghi := tcgppc(cg).rgint.getregister(list,R_SUBWHOLE); tmpreg64.reghi := tcgppc(cg).rg[R_INTREGISTER].getregister(list,R_SUBWHOLE);
a_load64_const_reg(list,value,tmpreg64); a_load64_const_reg(list,value,tmpreg64);
a_op64_reg_reg_reg(list,op,tmpreg64,regsrc,regdst); a_op64_reg_reg_reg(list,op,tmpreg64,regsrc,regdst);
tcgppc(cg).rgint.ungetregister(list,tmpreg64.reglo); tcgppc(cg).rg[R_INTREGISTER].ungetregister(list,tmpreg64.reglo);
tcgppc(cg).rgint.ungetregister(list,tmpreg64.reghi); tcgppc(cg).rg[R_INTREGISTER].ungetregister(list,tmpreg64.reghi);
end end
end end
else else
@ -2471,7 +2339,10 @@ begin
end. end.
{ {
$Log$ $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 * fixed compilation with -dppc603
Revision 1.144 2003/12/09 20:39:43 jonas Revision 1.144 2003/12/09 20:39:43 jonas

View File

@ -176,17 +176,32 @@ unit rgobj;
end; end;
Preginfo=^TReginfo; 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 This class implements the default register allocator. It is used by the
code generator to allocate and free registers which might be valid across code generator to allocate and free registers which might be valid
nodes. It also contains utility routines related to registers. across nodes. It also contains utility routines related to registers.
Some of the methods in this class should be overriden Some of the methods in this class should be overriden
by cpu-specific implementations. by cpu-specific implementations.
--------------------------------------------------------------------} --------------------------------------------------------------------}
trgobj=class trgobj=class(trgbase)
preserved_by_proc : tcpuregisterset; preserved_by_proc : tcpuregisterset;
used_in_proc : tcpuregisterset; used_in_proc : tcpuregisterset;
// is_reg_var : Tsuperregisterset; {old regvars} // is_reg_var : Tsuperregisterset; {old regvars}
@ -201,20 +216,20 @@ unit rgobj;
{# Allocate a register. An internalerror will be generated if there is {# Allocate a register. An internalerror will be generated if there is
no more free registers which can be allocated.} no more free registers which can be allocated.}
function getregister(list:Taasmoutput;subreg:Tsubregister):Tregister; function getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;virtual;
procedure add_constraints(reg:Tregister);virtual;
{# Get the register specified.} {# Get the register specified.}
procedure getexplicitregister(list:Taasmoutput;r:Tregister); procedure getexplicitregister(list:Taasmoutput;r:Tregister);virtual;
{# Get multiple registers specified.} {# Get multiple registers specified.}
procedure allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset); procedure allocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;
{# Free multiple registers specified.} {# Free multiple registers specified.}
procedure deallocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset); procedure deallocexplicitregisters(list:Taasmoutput;r:Tcpuregisterset);virtual;
function uses_registers:boolean; function uses_registers:boolean;virtual;
{# Deallocate any kind of register } {# Deallocate any kind of register }
procedure ungetregister(list:Taasmoutput;r:Tregister);virtual; procedure ungetregister(list:Taasmoutput;r:Tregister);virtual;
procedure add_constraints(reg:Tregister);virtual;
{# Do the register allocation.} {# Do the register allocation.}
procedure do_register_allocation(list:Taasmoutput;headertai:tai); procedure do_register_allocation(list:Taasmoutput;headertai:tai);virtual;
{ procedure resetusableregisters;virtual;} { procedure resetusableregisters;virtual;}
@ -615,11 +630,15 @@ implementation
function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister; function trgobj.getregister(list:Taasmoutput;subreg:Tsubregister):Tregister;
var p:Tsuperregister; var
p : Tsuperregister;
r : Tregister; r : Tregister;
begin begin
p:=getnewreg; p:=getnewreg;
supregset_exclude(unusedregs,p); supregset_exclude(unusedregs,p);
if defaultsub=R_SUBNONE then
r:=newreg(regtype,p,R_SUBNONE)
else
r:=newreg(regtype,p,subreg); r:=newreg(regtype,p,subreg);
list.concat(Tai_regalloc.alloc(r)); list.concat(Tai_regalloc.alloc(r));
add_edges_used(p); add_edges_used(p);
@ -1818,7 +1837,10 @@ implementation
end. end.
{ {
$Log$ $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 * remove redundant calls to add_edge_used
Revision 1.97 2003/11/29 17:36:41 peter Revision 1.97 2003/11/29 17:36:41 peter

View File

@ -36,27 +36,20 @@ unit cgx86;
type type
tcgx86 = class(tcg) tcgx86 = class(tcg)
rgint,
rgmm : trgcpu;
rgfpu : Trgx86fpu; rgfpu : Trgx86fpu;
procedure init_register_allocators;override; procedure init_register_allocators;override;
procedure done_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 getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
function getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
procedure getexplicitregister(list:Taasmoutput;r:Tregister);override; procedure getexplicitregister(list:Taasmoutput;r:Tregister);override;
procedure ungetregister(list:Taasmoutput;r:Tregister);override; procedure ungetregister(list:Taasmoutput;r:Tregister);override;
procedure ungetreference(list:Taasmoutput;const r:Treference);override; procedure ungetreference(list:Taasmoutput;const r:Treference);override;
procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override; procedure allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override; procedure deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);override;
function uses_registers(rt:Tregistertype):boolean;override; function uses_registers(rt:Tregistertype):boolean;override;
procedure add_move_instruction(instr:Taicpu);override;
procedure dec_fpu_stack; procedure dec_fpu_stack;
procedure inc_fpu_stack; procedure inc_fpu_stack;
procedure do_register_allocation(list:Taasmoutput;headertai:tai);override;
{ passing parameters, per default the parameter is pushed } { passing parameters, per default the parameter is pushed }
{ nr gives the number of the parameter (enumerated from } { nr gives the number of the parameter (enumerated from }
{ left to right), this allows to move the parameter to } { left to right), this allows to move the parameter to }
@ -176,123 +169,77 @@ unit cgx86;
procedure Tcgx86.init_register_allocators; procedure Tcgx86.init_register_allocators;
begin begin
if cs_create_pic in aktmoduleswitches then 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 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]); 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]);
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_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; rgfpu:=Trgx86fpu.create;
end; end;
procedure Tcgx86.done_register_allocators; procedure Tcgx86.done_register_allocators;
begin begin
rgint.free; rg[R_INTREGISTER].free;
rgmm.free; rg[R_INTREGISTER]:=nil;
rg[R_MMREGISTER].free;
rg[R_MMREGISTER]:=nil;
rgfpu.free; rgfpu.free;
end; 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; function Tcgx86.getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;
begin begin
result:=trgx86fpu(rgfpu).getregisterfpu(list); result:=rgfpu.getregisterfpu(list);
end;
function Tcgx86.getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;
begin
result:=rgmm.getregister(list,R_SUBNONE);
end; end;
procedure Tcgx86.getexplicitregister(list:Taasmoutput;r:Tregister); procedure Tcgx86.getexplicitregister(list:Taasmoutput;r:Tregister);
begin begin
case getregtype(r) of if getregtype(r)=R_FPUREGISTER then
R_INTREGISTER : internalerror(2003121210)
rgint.getexplicitregister(list,r);
R_SSEREGISTER :
rgmm.getexplicitregister(list,r);
else else
internalerror(200310091); inherited getexplicitregister(list,r);
end;
end; end;
procedure tcgx86.ungetregister(list:Taasmoutput;r:Tregister); procedure tcgx86.ungetregister(list:Taasmoutput;r:Tregister);
begin begin
case getregtype(r) of if getregtype(r)=R_FPUREGISTER then
R_INTREGISTER : rgfpu.ungetregisterfpu(list,r)
rgint.ungetregister(list,r);
R_FPUREGISTER :
rgfpu.ungetregisterfpu(list,r);
R_SSEREGISTER :
rgmm.ungetregister(list,r);
else else
internalerror(200310091); inherited ungetregister(list,r);
end;
end; end;
procedure tcgx86.ungetreference(list:Taasmoutput;const r:Treference); procedure tcgx86.ungetreference(list:Taasmoutput;const r:Treference);
begin begin
if r.base<>NR_NO then if r.base<>NR_NO then
rgint.ungetregister(list,r.base); ungetregister(list,r.base);
if r.index<>NR_NO then if r.index<>NR_NO then
rgint.ungetregister(list,r.index); ungetregister(list,r.index);
end; end;
procedure Tcgx86.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset); procedure Tcgx86.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
begin begin
case rt of if rt<>R_FPUREGISTER then
R_INTREGISTER : inherited allocexplicitregisters(list,rt,r);
rgint.allocexplicitregisters(list,r);
R_SSEREGISTER :
rgmm.allocexplicitregisters(list,r);
R_FPUREGISTER :
else
internalerror(200310092);
end;
end; end;
procedure Tcgx86.deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset); procedure Tcgx86.deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
begin begin
case rt of if rt<>R_FPUREGISTER then
R_INTREGISTER : inherited deallocexplicitregisters(list,rt,r);
rgint.deallocexplicitregisters(list,r);
R_SSEREGISTER :
rgmm.deallocexplicitregisters(list,r);
R_FPUREGISTER :
else
internalerror(200310093);
end;
end; end;
function Tcgx86.uses_registers(rt:Tregistertype):boolean; function Tcgx86.uses_registers(rt:Tregistertype):boolean;
begin begin
case rt of if rt=R_FPUREGISTER then
R_INTREGISTER : result:=false
result:=rgint.uses_registers;
R_SSEREGISTER :
result:=rgmm.uses_registers;
R_FPUREGISTER :
result:=false;
else else
internalerror(200310094); result:=inherited uses_registers(rt);
end;
end;
procedure Tcgx86.add_move_instruction(instr:Taicpu);
begin
rgint.add_move_instruction(instr);
end; end;
@ -308,20 +255,6 @@ unit cgx86;
end; 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! :) This is private property, keep out! :)
****************************************************************************} ****************************************************************************}
@ -706,7 +639,7 @@ unit cgx86;
instr:=taicpu.op_reg_reg(op,s,reg1,reg2); instr:=taicpu.op_reg_reg(op,s,reg1,reg2);
{Notify the register allocator that we have written a move instruction so {Notify the register allocator that we have written a move instruction so
it can try to eliminate it.} it can try to eliminate it.}
Tcgx86(cg).rgint.add_move_instruction(instr); add_move_instruction(instr);
list.concat(instr); list.concat(instr);
end; end;
@ -1513,7 +1446,7 @@ unit cgx86;
list.concat(Tai_section.Create(sec_code)); list.concat(Tai_section.Create(sec_code));
list.concat(Taicpu.Op_sym_ofs_reg(A_MOV,S_L,pl,0,NR_EDX)); list.concat(Taicpu.Op_sym_ofs_reg(A_MOV,S_L,pl,0,NR_EDX));
a_call_name(list,target_info.Cprefix+mcountprefix+'mcount'); 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; end;
system_i386_go32v2,system_i386_watcom: system_i386_go32v2,system_i386_watcom:
@ -1575,7 +1508,7 @@ unit cgx86;
begin begin
list.concat(tai_regalloc.alloc(NR_EBP)); 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(A_PUSH,S_L,NR_EBP));
list.concat(Taicpu.op_reg_reg(A_MOV,S_L,NR_ESP,NR_EBP)); list.concat(Taicpu.op_reg_reg(A_MOV,S_L,NR_ESP,NR_EBP));
if localsize>0 then if localsize>0 then
@ -1633,36 +1566,36 @@ unit cgx86;
begin begin
{ Get temp } { Get temp }
size:=0; 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); 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); 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); inc(size,POINTER_SIZE);
if size>0 then if size>0 then
begin begin
tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref); tg.GetTemp(list,size,tt_noreuse,current_procinfo.save_regs_ref);
{ Copy registers to temp } { Copy registers to temp }
href:=current_procinfo.save_regs_ref; 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 begin
a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EBX,href); a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EBX,href);
inc(href.offset,POINTER_SIZE); inc(href.offset,POINTER_SIZE);
end; end;
if RS_ESI in rgint.used_in_proc then if RS_ESI in rg[R_INTREGISTER].used_in_proc then
begin begin
a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_ESI,href); a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_ESI,href);
inc(href.offset,POINTER_SIZE); inc(href.offset,POINTER_SIZE);
end; end;
if RS_EDI in rgint.used_in_proc then if RS_EDI in rg[R_INTREGISTER].used_in_proc then
begin begin
a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EDI,href); a_load_reg_ref(list,OS_ADDR,OS_ADDR,NR_EDI,href);
inc(href.offset,POINTER_SIZE); inc(href.offset,POINTER_SIZE);
end; end;
end; end;
include(rgint.preserved_by_proc,RS_EBX); include(rg[R_INTREGISTER].preserved_by_proc,RS_EBX);
include(rgint.preserved_by_proc,RS_ESI); include(rg[R_INTREGISTER].preserved_by_proc,RS_ESI);
include(rgint.preserved_by_proc,RS_EDI); include(rg[R_INTREGISTER].preserved_by_proc,RS_EDI);
end; end;
@ -1672,17 +1605,17 @@ unit cgx86;
begin begin
{ Copy registers from temp } { Copy registers from temp }
href:=current_procinfo.save_regs_ref; 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 begin
a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EBX); a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EBX);
inc(href.offset,POINTER_SIZE); inc(href.offset,POINTER_SIZE);
end; end;
if RS_ESI in rgint.used_in_proc then if RS_ESI in rg[R_INTREGISTER].used_in_proc then
begin begin
a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_ESI); a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_ESI);
inc(href.offset,POINTER_SIZE); inc(href.offset,POINTER_SIZE);
end; end;
if RS_EDI in rgint.used_in_proc then if RS_EDI in rg[R_INTREGISTER].used_in_proc then
begin begin
a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EDI); a_load_ref_reg(list,OS_ADDR,OS_ADDR,href,NR_EDI);
inc(href.offset,POINTER_SIZE); inc(href.offset,POINTER_SIZE);
@ -1751,7 +1684,10 @@ unit cgx86;
end. end.
{ {
$Log$ $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 * reverted Peter's alloctemp patch; hopefully properly
Revision 1.88 2003/12/03 23:13:20 peter Revision 1.88 2003/12/03 23:13:20 peter