* added more register functions

This commit is contained in:
peter 2003-10-24 15:20:37 +00:00
parent 619b429650
commit b224d87ea5
2 changed files with 194 additions and 70 deletions

View File

@ -31,17 +31,27 @@ interface
aasmbase,aasmtai,aasmcpu,
cpubase,cpuinfo,
node,symconst,SymType,
RgCpu;
rgcpu;
type
TCgSparc=class(tcg)
protected
rgint,
rgfpu : trgcpu;
rgfpu : trgcpu;
function IsSimpleRef(const ref:treference):boolean;
public
procedure init_register_allocators;override;
procedure done_register_allocators;override;
function getintregister(list:Taasmoutput;size:Tcgsize):Tregister;override;
function getaddressregister(list:Taasmoutput):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 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;
{ sparc special, needed by cg64 }
procedure handle_load_store(list:taasmoutput;isstore:boolean;op: tasmop;reg:tregister;ref: treference);
procedure handle_reg_const_reg(list:taasmoutput;op:Tasmop;src:tregister;a:aword;dst:tregister);
@ -51,6 +61,8 @@ interface
procedure a_paramaddr_ref(list:TAasmOutput;const r:TReference;const LocPara:TParaLocation);override;
procedure a_paramfpu_reg(list : taasmoutput;size : tcgsize;const r : tregister;const locpara : tparalocation);override;
procedure a_paramfpu_ref(list : taasmoutput;size : tcgsize;const ref : treference;const locpara : tparalocation);override;
procedure a_loadany_param_ref(list : taasmoutput;const locpara : tparalocation;const ref:treference;shuffle : pmmshuffle);override;
procedure a_loadany_param_reg(list : taasmoutput;const locpara : tparalocation;const reg:tregister;shuffle : pmmshuffle);override;
procedure a_call_name(list:TAasmOutput;const s:string);override;
procedure a_call_reg(list:TAasmOutput;Reg:TRegister);override;
{ General purpose instructions }
@ -108,7 +120,7 @@ implementation
uses
globtype,globals,verbose,systems,cutils,
symdef,symsym,defutil,paramgr,
rgobj,tgobj,cpupi;
tgobj,cpupi;
{****************************************************************************
@ -222,20 +234,121 @@ implementation
procedure Tcgsparc.init_register_allocators;
begin
{rg:=Trgcpu.create(15,chr(RS_O0)+chr(RS_O1)+chr(RS_O2)+chr(RS_O3)+
chr(RS_O4)+chr(RS_O5)+chr(RS_O7)+
chr(RS_L0)+chr(RS_L1)+chr(RS_L2)+chr(RS_L3)+
chr(RS_L4)+chr(RS_L5)+chr(RS_L6)+chr(RS_L7));}
rgint:=TrgCpu.create(R_INTREGISTER,R_SUBWHOLE,[RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,RS_O7,RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7],first_int_imreg,[]);
{$warning FIX ME}
rgint:=Trgcpu.create(R_INTREGISTER,R_SUBWHOLE,
[RS_O0,RS_O1,RS_O2,RS_O3,RS_O4,RS_O5,RS_O7,
RS_L0,RS_L1,RS_L2,RS_L3,RS_L4,RS_L5,RS_L6,RS_L7],
first_int_imreg,[]);
rgfpu:=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_F14,RS_F15,RS_F16,RS_F17,RS_F18,RS_F19,RS_F20,RS_F21,RS_F22,RS_F23,RS_F24,RS_F25,RS_F26,RS_F27,RS_F28,RS_F29,RS_F30,RS_F31],first_fpu_imreg,[]);
[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_F14,RS_F15,
RS_F16,RS_F17,RS_F18,RS_F19,RS_F20,RS_F21,RS_F22,RS_F23,
RS_F24,RS_F25,RS_F26,RS_F27,RS_F28,RS_F29,RS_F30,RS_F31],
first_fpu_imreg,[]);
end;
procedure Tcgsparc.done_register_allocators;
begin
rgint.free;
rgfpu.free;
end;
function tcgsparc.getintregister(list:Taasmoutput;size:Tcgsize):Tregister;
begin
result:=rgint.getregister(list,R_SUBWHOLE);
end;
function tcgsparc.getaddressregister(list:Taasmoutput):Tregister;
begin
result:=rgint.getregister(list,R_SUBWHOLE);
end;
function tcgsparc.getfpuregister(list:Taasmoutput;size:Tcgsize):Tregister;
begin
if size=OS_F64 then
result:=rgfpu.getregister(list,R_SUBFD)
else
result:=rgfpu.getregister(list,R_SUBWHOLE);
end;
function tcgsparc.getmmregister(list:Taasmoutput;size:Tcgsize):Tregister;
begin
internalerror(200310241);
result:=RS_INVALID;
end;
procedure tcgsparc.getexplicitregister(list:Taasmoutput;r:Tregister);
begin
case getregtype(r) of
R_INTREGISTER :
rgint.getexplicitregister(list,r);
R_FPUREGISTER :
rgfpu.getexplicitregister(list,r);
else
internalerror(200310091);
end;
end;
procedure tcgsparc.ungetregister(list:Taasmoutput;r:Tregister);
begin
case getregtype(r) of
R_INTREGISTER :
rgint.ungetregister(list,r);
R_FPUREGISTER :
rgfpu.ungetregister(list,r);
else
internalerror(200310091);
end;
end;
procedure tcgsparc.allocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
begin
case rt of
R_INTREGISTER :
rgint.allocexplicitregisters(list,r);
R_FPUREGISTER :
rgfpu.allocexplicitregisters(list,r);
else
internalerror(200310092);
end;
end;
procedure tcgsparc.deallocexplicitregisters(list:Taasmoutput;rt:Tregistertype;r:Tcpuregisterset);
begin
case rt of
R_INTREGISTER :
rgint.deallocexplicitregisters(list,r);
R_FPUREGISTER :
rgfpu.deallocexplicitregisters(list,r);
else
internalerror(200310093);
end;
end;
procedure tcgsparc.add_move_instruction(instr:Taicpu);
begin
rgint.add_move_instruction(instr);
end;
procedure tcgsparc.do_register_allocation(list:Taasmoutput;headertai:tai);
begin
{ Int }
rgint.do_register_allocation(list,headertai);
rgint.translate_registers(list);
{ FPU }
rgfpu.do_register_allocation(list,headertai);
rgfpu.translate_registers(list);
end;
@ -350,6 +463,55 @@ implementation
end;
procedure tcgsparc.a_loadany_param_ref(list : taasmoutput;const locpara : tparalocation;const ref:treference;shuffle : pmmshuffle);
var
href,
tempref : treference;
templocpara : tparalocation;
begin
{ Load floats like ints }
templocpara:=locpara;
case locpara.size of
OS_F32 :
templocpara.size:=OS_32;
OS_F64 :
templocpara.size:=OS_64;
end;
{ Word 0 is in register, word 1 is in reference }
if (templocpara.loc=LOC_REFERENCE) and (templocpara.low_in_reg) then
begin
tempref:=ref;
cg.a_load_reg_ref(list,OS_INT,OS_INT,templocpara.register,tempref);
inc(tempref.offset,4);
reference_reset_base(href,templocpara.reference.index,templocpara.reference.offset);
cg.a_load_ref_ref(list,OS_INT,OS_INT,href,tempref);
end
else
inherited a_loadany_param_ref(list,templocpara,ref,shuffle);
end;
procedure tcgsparc.a_loadany_param_reg(list : taasmoutput;const locpara : tparalocation;const reg:tregister;shuffle : pmmshuffle);
var
href : treference;
begin
{ Word 0 is in register, word 1 is in reference, not
possible to load it in 1 register }
if (locpara.loc=LOC_REFERENCE) and (locpara.low_in_reg) then
internalerror(200307011);
{ Float load use a temp reference }
if locpara.size in [OS_F32,OS_F64] then
begin
tg.GetTemp(list,TCGSize2Size[locpara.size],tt_normal,href);
a_loadany_param_ref(list,locpara,href,shuffle);
a_loadfpu_ref_reg(list,locpara.size,href,reg);
tg.Ungettemp(list,href);
end
else
inherited a_loadany_param_reg(list,locpara,reg,shuffle);
end;
procedure TCgSparc.a_call_name(list:TAasmOutput;const s:string);
begin
list.concat(taicpu.op_sym(A_CALL,objectlibrary.newasmsymbol(s)));
@ -1052,7 +1214,10 @@ begin
end.
{
$Log$
Revision 1.70 2003-10-24 11:14:46 mazen
Revision 1.71 2003-10-24 15:20:37 peter
* added more register functions
Revision 1.70 2003/10/24 11:14:46 mazen
* rg.[un]GetRegister* ==> [Un]Get[*]Register
Revision 1.69 2003/10/01 20:34:49 peter

View File

@ -27,85 +27,44 @@ unit rgcpu;
interface
uses
cpubase,
cpuinfo,
aasmcpu,
aasmtai,
cclasses,globtype,
cgbase,aasmbase,rgobj;
cgbase,rgobj;
type
trgcpu=class(trgobj)
function GetRegisterFpu(list:TAasmOutput;size:Tcgsize):TRegister;override;
procedure UngetRegisterFpu(list:taasmoutput;reg:tregister;size:TCGsize);override;
procedure add_constraints(reg:tregister);override;
end;
implementation
uses
cgobj,verbose;
cpubase;
function TRgCpu.GetRegisterFpu(list:TAasmOutput;size:Tcgsize):TRegister;
procedure trgcpu.add_constraints(reg:tregister);
var
i: Tsuperregister;
supreg,i: Tsuperregister;
r: Tregister;
begin
for i:=firstsavefpureg to lastsavefpureg do
begin
if (i in unusedregsfpu) and
(
(size=OS_F32) or
(not odd(i-RS_F0))
) then
begin
exclude(unusedregsfpu,i);
dec(countunusedregsfpu);
r:=newreg(R_FPUREGISTER,i,R_SUBNONE);
list.concat(tai_regalloc.alloc(r));
result := r;
{ double need 2 FPU registers }
if size=OS_F64 then
begin
r:=newreg(R_FPUREGISTER,i+1,R_SUBNONE);
exclude(unusedregsfpu,i+1);
dec(countunusedregsfpu);
list.concat(tai_regalloc.alloc(r));
end;
exit;
end;
end;
internalerror(10);
end;
procedure trgcpu.UngetRegisterFpu(list:taasmoutput;reg:tregister;size:TCGsize);
var
r : tregister;
supreg : tsuperregister;
begin
supreg:=getsupreg(reg);
{ double need 2 FPU registers }
if (size=OS_F64) then
{ Let 64bit floats conflict with all odd float regs }
if getsubreg(reg)=R_SUBFD then
begin
{ Only even FP registers are allowed }
if odd(supreg-RS_F0) then
internalerror(200306101);
r:=newreg(R_FPUREGISTER,supreg+1,R_SUBNONE);
inc(countunusedregsfpu);
include(unusedregsfpu,getsupreg(r));
list.concat(tai_regalloc.dealloc(r));
supreg:=getsupreg(reg);
i:=RS_F1;
while (i<=RS_F31) do
begin
add_edge(supreg,i);
inc(i,2);
end;
end;
inc(countunusedregsfpu);
include(unusedregsfpu,supreg);
list.concat(tai_regalloc.dealloc(reg));
end;
end.
{
$Log$
Revision 1.19 2003-10-01 20:34:50 peter
Revision 1.20 2003-10-24 15:20:37 peter
* added more register functions
Revision 1.19 2003/10/01 20:34:50 peter
* procinfo unit contains tprocinfo
* cginfo renamed to cgbase
* moved cgmessage to verbose