* fix compilation for avr

* some ideas for avr register management
+ initial implementation of a_load_reg_reg

git-svn-id: trunk@17007 -
This commit is contained in:
florian 2011-02-26 20:02:45 +00:00
parent b7e26ed986
commit 4cfc5693c5
2 changed files with 350 additions and 69 deletions

View File

@ -36,12 +36,21 @@ unit cgcpu;
type type
{ tcgavr }
tcgavr = class(tcg) tcgavr = class(tcg)
{ true, if the next arithmetic operation should modify the flags } { true, if the next arithmetic operation should modify the flags }
cgsetflags : boolean; cgsetflags : boolean;
procedure init_register_allocators;override; procedure init_register_allocators;override;
procedure done_register_allocators;override; procedure done_register_allocators;override;
function getintregister(list:TAsmList;size:Tcgsize):Tregister;override;
function getaddressregister(list:TAsmList):Tregister;override;
procedure prepareref(list: TAsmList; var r: treference);
procedure incabsref(list: TAsmList;var r: treference);
procedure a_load_const_cgpara(list : TAsmList;size : tcgsize;a : aint;const paraloc : TCGPara);override; procedure a_load_const_cgpara(list : TAsmList;size : tcgsize;a : aint;const paraloc : TCGPara);override;
procedure a_load_ref_cgpara(list : TAsmList;size : tcgsize;const r : treference;const paraloc : TCGPara);override; procedure a_load_ref_cgpara(list : TAsmList;size : tcgsize;const r : treference;const paraloc : TCGPara);override;
procedure a_loadaddr_ref_cgpara(list : TAsmList;const r : treference;const paraloc : TCGPara);override; procedure a_loadaddr_ref_cgpara(list : TAsmList;const r : treference;const paraloc : TCGPara);override;
@ -65,8 +74,6 @@ unit cgcpu;
procedure a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);override; procedure a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);override;
procedure a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override; procedure a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override;
procedure a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);override; procedure a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);override;
function a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
function a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
{ comparison operations } { comparison operations }
procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister; procedure a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
@ -100,6 +107,8 @@ unit cgcpu;
function handle_load_store(list:TAsmList;op: tasmop;reg:tregister;ref: treference):treference; function handle_load_store(list:TAsmList;op: tasmop;reg:tregister;ref: treference):treference;
procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override; procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
procedure emit_mov(list: TAsmList;reg2: tregister; reg1: tregister);
end; end;
tcg64favr = class(tcg64f32) tcg64favr = class(tcg64f32)
@ -146,6 +155,64 @@ unit cgcpu;
end; end;
function tcgavr.getintregister(list: TAsmList; size: Tcgsize): Tregister;
var
tmp1,tmp2,tmp3 : TRegister;
begin
case size of
OS_8,OS_S8:
Result:=inherited getintregister(list, size);
OS_16,OS_S16:
begin
Result:=inherited getintregister(list, OS_8);
{ ensure that the high register can be retrieved by
GetNextReg
}
if inherited getintregister(list, OS_8)<>GetNextReg(Result) then
internalerror(2011021331);
end;
OS_32,OS_S32:
begin
Result:=inherited getintregister(list, OS_8);
tmp1:=inherited getintregister(list, OS_8);
{ ensure that the high register can be retrieved by
GetNextReg
}
if tmp1<>GetNextReg(Result) then
internalerror(2011021332);
tmp2:=inherited getintregister(list, OS_8);
{ ensure that the upper register can be retrieved by
GetNextReg
}
if tmp2<>GetNextReg(tmp1) then
internalerror(2011021333);
tmp3:=inherited getintregister(list, OS_8);
{ ensure that the upper register can be retrieved by
GetNextReg
}
if tmp3<>GetNextReg(tmp2) then
internalerror(2011021334);
end;
else
internalerror(2011021330);
end;
end;
function tcgavr.getaddressregister(list: TAsmList): Tregister;
var
supreg,i : tsuperregister;
begin
Result:=getintregister(list,OS_16);
supreg:=getsupreg(Result);
for i:=RS_R0 to RS_R25 do
rg[R_INTREGISTER].add_edge(supreg,i);
rg[R_INTREGISTER].add_edge(supreg,RS_R27);
rg[R_INTREGISTER].add_edge(supreg,RS_R29);
rg[R_INTREGISTER].add_edge(supreg,RS_R31);
end;
procedure tcgavr.a_load_const_cgpara(list : TAsmList;size : tcgsize;a : aint;const paraloc : TCGPara); procedure tcgavr.a_load_const_cgpara(list : TAsmList;size : tcgsize;a : aint;const paraloc : TCGPara);
var var
ref: treference; ref: treference;
@ -282,21 +349,31 @@ unit cgcpu;
procedure tcgavr.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); procedure tcgavr.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister);
var
tmpreg: tregister;
begin begin
internalerror(2011021301);
case op of case op of
OP_NEG: OP_NEG:
// !!!! list.concat(taicpu.op_reg_reg_const(A_RSB,dst,src,0)); if src<>dst then
; a_load_reg_reg(list,size,size,src,dst);
list.concat(taicpu.op_reg(A_NEG,dst));
if size in [OS_S16,OS_16,OS_S32,OS_32] then
begin
tmpreg:=GetNextReg(dst);
list.concat(taicpu.op_reg(A_NOT,S_L,));
list.concat(taicpu.op_reg(A_NEG,S_L,regdst.reglo));
list.concat(taicpu.op_const_reg(A_SBB,S_L,-1,regdst.reghi));
end;
OP_NOT: OP_NOT:
begin begin
// !!!! list.concat(taicpu.op_reg_reg(A_MVN,dst,src)); for i:=1 to cgsize2size[size] do
case size of begin
OS_8 : if src<>dst then
; a_load_reg_reg(list,OS_8,OS_8,src,dst);
// !!!! a_op_const_reg_reg(list,OP_AND,OS_INT,$ff,dst,dst); list.concat(taicpu.op_reg(A_NOT,S_L,dst));
OS_16 : src:=GetNextReg(src);
// !!!! a_op_const_reg_reg(list,OP_AND,OS_INT,$ffff,dst,dst); dst:=GetNextReg(dst);
;
end; end;
end end
else else
@ -325,6 +402,7 @@ unit cgcpu;
procedure tcgavr.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: aint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); procedure tcgavr.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: aint; src, dst: tregister;setflags : boolean;var ovloc : tlocation);
begin begin
internalerror(2011021302);
end; end;
@ -334,6 +412,7 @@ unit cgcpu;
tmpreg,overflowreg : tregister; tmpreg,overflowreg : tregister;
asmop : tasmop; asmop : tasmop;
begin begin
internalerror(2011021303);
ovloc.loc:=LOC_VOID; ovloc.loc:=LOC_VOID;
case op of case op of
OP_NEG,OP_NOT, OP_NEG,OP_NOT,
@ -365,67 +444,243 @@ unit cgcpu;
function tcgavr.handle_load_store(list:TAsmList;op: tasmop;reg:tregister;ref: treference):treference; function tcgavr.handle_load_store(list:TAsmList;op: tasmop;reg:tregister;ref: treference):treference;
begin begin
internalerror(2011021304);
end; end;
procedure tcgavr.a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference); procedure tcgavr.a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);
begin begin
internalerror(2011021305);
end; end;
procedure tcgarm.a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister); procedure tcgavr.a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);
{
var var
oppostfix:toppostfix; oppostfix:toppostfix;
usedtmpref: treference; usedtmpref: treference;
tmpreg,tmpreg2 : tregister; tmpreg,tmpreg2 : tregister;
so : tshifterop; so : tshifterop;
dir : integer; dir : integer;
}
begin begin
if (TCGSize2Size[FromSize] >= TCGSize2Size[ToSize]) then internalerror(2011021306);
FromSize := ToSize; //if (TCGSize2Size[FromSize] >= TCGSize2Size[ToSize]) then
case FromSize of // FromSize := ToSize;
{ signed integer registers } //case FromSize of
OS_8: // { signed integer registers }
oppostfix:=PF_B; // OS_8:
OS_S8: // oppostfix:=PF_B;
oppostfix:=PF_SB; // OS_S8:
OS_16: // oppostfix:=PF_SB;
oppostfix:=PF_H; // OS_16:
OS_S16: // oppostfix:=PF_H;
oppostfix:=PF_SH; // OS_S16:
OS_32, // oppostfix:=PF_SH;
OS_S32: // OS_32,
oppostfix:=PF_None; // OS_S32:
else // oppostfix:=PF_None;
InternalError(200308297); // else
end; // InternalError(200308297);
handle_load_store(list,A_LDR,oppostfix,reg,ref); //end;
//handle_load_store(list,A_LDR,oppostfix,reg,ref);
if (fromsize=OS_S8) and (tosize = OS_16) then //
a_load_reg_reg(list,OS_16,OS_32,reg,reg); //if (fromsize=OS_S8) and (tosize = OS_16) then
// a_load_reg_reg(list,OS_16,OS_32,reg,reg);
end; end;
procedure tcgavr.prepareref(list : TAsmList; var r : treference);
begin
end;
procedure tcgavr.incref(list: TAsmList; var r: treference);
begin
end;
procedure tcgavr.a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister); procedure tcgavr.a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);
var var
href : treference; href : treference;
conv_done: boolean;
tmpreg : tregister;
begin begin
if (ref.base=R_NO) and (ref.index=R_NO) then href:=Ref;
prepareref(list,href);
if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
internalerror(2011021307);
conv_done:=false;
if tosize<>fromsize then
begin
conv_done:=true;
if tcgsize2size[tosize]<=tcgsize2size[fromsize] then
fromsize:=tosize;
case fromsize of
OS_8:
begin
list.concat(taicpu.op_reg_ref(A_LD,reg,href));
for i:=2 to tcgsize2size[tosize] do
begin
reg:=GetNextReg(reg);
list.concat(taicpu.op_reg(A_CLR,reg));
end;
end;
OS_S8:
begin
{ dest is always at least 16 bit at this point }
list.concat(taicpu.op_reg_ref(A_LD,reg,href));
tmpreg:=reg;
reg2:=GetNextReg(reg);
list.concat(taicpu.op_reg(A_CLR,reg));
list.concat(taicpu.op_reg_const(A_SBIC,tmpreg,7));
list.concat(taicpu.op_reg(A_COM,reg));
tmpreg:=register;
for i:=3 to tcgsize2size[tosize] do
begin
reg:=GetNextReg(reg);
emit_mov(list,reg2,tmpreg);
end;
end;
OS_16:
begin
incref(href);
list.concat(taicpu.op_reg_ref(A_LD,reg,href));
reg:=GetNextReg(reg);
list.concat(taicpu.op_reg_ref(A_LD,reg,href));
for i:=3 to tcgsize2size[tosize] do
begin
reg:=GetNextReg(reg);
list.concat(taicpu.op_reg(A_CLR,reg));
end;
end;
OS_S16:
begin
{ dest is always at least 32 bit at this point }
emit_mov(list,reg2,reg1);
reg1:=GetNextReg(reg1);
reg2:=GetNextReg(reg2);
emit_mov(list,reg2,reg1);
reg2:=GetNextReg(reg2);
list.concat(taicpu.op_reg(A_CLR,reg2));
list.concat(taicpu.op_reg_const(A_SBIC,reg1,7));
list.concat(taicpu.op_reg(A_COM,reg2));
tmpreg:=register;
for i:=4 to tcgsize2size[tosize] do
begin
reg2:=GetNextReg(reg2);
emit_mov(list,reg2,tmpreg);
end;
end;
else
conv_done:=false;
end;
end;
if not conv_done and (reg1<>reg2) then
begin
for i:=1 to tcgsize2size[fromsize] do
begin
emit_mov(list,reg2,reg1);
reg1:=GetNextReg(reg1);
reg2:=GetNextReg(reg2);
end;
end;
end; end;
function tcgavr.a_internal_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference):treference;
begin
end;
function tcgavr.a_internal_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister):treference;
begin
end;
procedure tcgavr.a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister); procedure tcgavr.a_load_reg_reg(list : TAsmList; fromsize, tosize : tcgsize;reg1,reg2 : tregister);
var
conv_done: boolean;
tmpreg : tregister;
begin begin
if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
internalerror(2011021310);
conv_done:=false;
if tosize<>fromsize then
begin
conv_done:=true;
if tcgsize2size[tosize]<=tcgsize2size[fromsize] then
fromsize:=tosize;
case fromsize of
OS_8:
begin
emit_mov(list,reg2,reg1);
for i:=2 to tcgsize2size[tosize] do
begin
reg2:=GetNextReg(reg2);
list.concat(taicpu.op_reg(A_CLR,reg2));
end;
end;
OS_S8:
begin
{ dest is always at least 16 bit at this point }
emit_mov(list,reg2,reg1);
reg2:=GetNextReg(reg2);
list.concat(taicpu.op_reg(A_CLR,reg2));
list.concat(taicpu.op_reg_const(A_SBIC,reg1,7));
list.concat(taicpu.op_reg(A_COM,reg2));
tmpreg:=register;
for i:=3 to tcgsize2size[tosize] do
begin
reg2:=GetNextReg(reg2);
emit_mov(list,reg2,tmpreg);
end;
end;
OS_16:
begin
emit_mov(list,reg2,reg1);
reg1:=GetNextReg(reg1);
reg2:=GetNextReg(reg2);
emit_mov(list,reg2,reg1);
for i:=3 to tcgsize2size[tosize] do
begin
reg2:=GetNextReg(reg2);
list.concat(taicpu.op_reg(A_CLR,reg2));
end;
end;
OS_S16:
begin
{ dest is always at least 32 bit at this point }
emit_mov(list,reg2,reg1);
reg1:=GetNextReg(reg1);
reg2:=GetNextReg(reg2);
emit_mov(list,reg2,reg1);
reg2:=GetNextReg(reg2);
list.concat(taicpu.op_reg(A_CLR,reg2));
list.concat(taicpu.op_reg_const(A_SBIC,reg1,7));
list.concat(taicpu.op_reg(A_COM,reg2));
tmpreg:=register;
for i:=4 to tcgsize2size[tosize] do
begin
reg2:=GetNextReg(reg2);
emit_mov(list,reg2,tmpreg);
end;
end;
else
conv_done:=false;
end;
end;
if not conv_done and (reg1<>reg2) then
begin
for i:=1 to tcgsize2size[fromsize] do
begin
emit_mov(list,reg2,reg1);
reg1:=GetNextReg(reg1);
reg2:=GetNextReg(reg2);
end;
end;
end; end;
@ -433,31 +688,37 @@ unit cgcpu;
procedure tcgavr.a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister; procedure tcgavr.a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
l : tasmlabel); l : tasmlabel);
begin begin
internalerror(2011021311);
end; end;
procedure tcgavr.a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel); procedure tcgavr.a_cmp_reg_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;reg1,reg2 : tregister;l : tasmlabel);
begin begin
internalerror(2011021312);
end; end;
procedure tcgavr.a_jmp_name(list : TAsmList;const s : string); procedure tcgavr.a_jmp_name(list : TAsmList;const s : string);
begin begin
internalerror(2011021313);
end; end;
procedure tcgavr.a_jmp_always(list : TAsmList;l: tasmlabel); procedure tcgavr.a_jmp_always(list : TAsmList;l: tasmlabel);
begin begin
internalerror(2011021314);
end; end;
procedure tcgavr.a_jmp_flags(list : TAsmList;const f : TResFlags;l: tasmlabel); procedure tcgavr.a_jmp_flags(list : TAsmList;const f : TResFlags;l: tasmlabel);
begin begin
internalerror(2011021315);
end; end;
procedure tcgavr.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister); procedure tcgavr.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister);
begin begin
internalerror(2011021316);
end; end;
@ -471,6 +732,7 @@ unit cgcpu;
regs : tcpuregisterset; regs : tcpuregisterset;
} }
begin begin
internalerror(2011021317);
{ {
LocalSize:=align(LocalSize,4); LocalSize:=align(LocalSize,4);
if not(nostackframe) then if not(nostackframe) then
@ -619,6 +881,7 @@ unit cgcpu;
LocalSize : longint; LocalSize : longint;
} }
begin begin
internalerror(2011021318);
{ {
if not(nostackframe) then if not(nostackframe) then
begin begin
@ -699,11 +962,13 @@ unit cgcpu;
procedure tcgavr.a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister); procedure tcgavr.a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);
begin begin
internalerror(2011021319);
end; end;
procedure tcgavr.fixref(list : TAsmList;var ref : treference); procedure tcgavr.fixref(list : TAsmList;var ref : treference);
begin begin
internalerror(2011021320);
end; end;
@ -734,6 +999,7 @@ unit cgcpu;
procedure tcgavr.g_concatcopy_internal(list : TAsmList;const source,dest : treference;len : aint;aligned : boolean); procedure tcgavr.g_concatcopy_internal(list : TAsmList;const source,dest : treference;len : aint;aligned : boolean);
begin begin
internalerror(2011021321);
end; end;
procedure tcgavr.g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint); procedure tcgavr.g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint);
@ -763,6 +1029,7 @@ unit cgcpu;
procedure tcgavr.g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation); procedure tcgavr.g_overflowCheck_loc(List:TAsmList;const Loc:TLocation;def:TDef;ovloc : tlocation);
begin begin
internalerror(2011021322);
end; end;
{ {
@ -791,11 +1058,25 @@ unit cgcpu;
procedure tcgavr.g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint); procedure tcgavr.g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);
begin begin
internalerror(2011021324);
end;
procedure tcgavr.emit_mov(list: TAsmList;reg2: tregister; reg1: tregister);
var
instr: taicpu;
begin
list.concat(taicpu.op_reg_reg(A_MOV, reg2, reg1));
list.Concat(instr);
{ Notify the register allocator that we have written a move instruction so
it can try to eliminate it. }
add_move_instruction(instr);
end; end;
procedure tcg64favr.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64); procedure tcg64favr.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
begin begin
internalerror(2011021325);
end; end;
@ -823,11 +1104,13 @@ unit cgcpu;
procedure tcg64favr.a_op64_const_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation); procedure tcg64favr.a_op64_const_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
begin begin
internalerror(2011021326);
end; end;
procedure tcg64favr.a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation); procedure tcg64favr.a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
begin begin
internalerror(2011021327);
end; end;

View File

@ -156,18 +156,7 @@ unit cpubase;
Operands Operands
*****************************************************************************} *****************************************************************************}
taddressmode = (AM_OFFSET,AM_PREINDEXED,AM_POSTINDEXED); taddressmode = (AM_UNCHANGED,AM_POSTINCREMENT,AM_PREDRECEMENT);
tshiftmode = (SM_None,SM_LSL,SM_LSR,SM_ASR,SM_ROR,SM_RRX);
tupdatereg = (UR_None,UR_Update);
pshifterop = ^tshifterop;
tshifterop = record
shiftmode : tshiftmode;
rs : tregister;
shiftimm : byte;
end;
{***************************************************************************** {*****************************************************************************
Constants Constants
@ -347,6 +336,9 @@ unit cpubase;
function dwarf_reg(r:tregister):byte; function dwarf_reg(r:tregister):byte;
function GetHigh(const r : TRegister) : TRegister; function GetHigh(const r : TRegister) : TRegister;
{ returns the next virtual register }
function GetNextReg(const r : TRegister) : TRegister;
implementation implementation
uses uses
@ -482,4 +474,10 @@ unit cpubase;
result:=TRegister(longint(r)+1) result:=TRegister(longint(r)+1)
end; end;
function GetNextReg(const r: TRegister): TRegister;
begin
result:=TRegister(longint(r)+1);
end;
end. end.