summaryrefslogtreecommitdiff
path: root/compiler/avr
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2011-04-19 20:17:52 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2011-04-19 20:17:52 +0000
commit2dca8fd004f11acbb1d4f5825b8f43645b9438f4 (patch)
tree60c6228d001e260c8ef3901dc295d55f0ba9425e /compiler/avr
parentc38b26532690a89dd936037853fee2fc042b13dd (diff)
downloadfpc-2dca8fd004f11acbb1d4f5825b8f43645b9438f4.tar.gz
* reintegrate avr branch into trunk, work on avr is less invasive than I thought so it can be continued in trunk
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@17348 3ad0048d-3df7-0310-abae-a5850022a9f2
Diffstat (limited to 'compiler/avr')
-rw-r--r--compiler/avr/aasmcpu.pas28
-rw-r--r--compiler/avr/agavrgas.pas159
-rw-r--r--compiler/avr/aoptcpu.pas38
-rw-r--r--compiler/avr/cgcpu.pas690
-rw-r--r--compiler/avr/cpubase.pas31
-rw-r--r--compiler/avr/cpuinfo.pas49
-rw-r--r--compiler/avr/cpupara.pas22
-rw-r--r--compiler/avr/cpupi.pas16
-rw-r--r--compiler/avr/itcpugas.pas2
-rw-r--r--compiler/avr/navradd.pas34
-rw-r--r--compiler/avr/navrcnv.pas123
-rw-r--r--compiler/avr/raavrgas.pas19
-rw-r--r--compiler/avr/rgcpu.pas66
13 files changed, 868 insertions, 409 deletions
diff --git a/compiler/avr/aasmcpu.pas b/compiler/avr/aasmcpu.pas
index d8dfe60d34..3902623a88 100644
--- a/compiler/avr/aasmcpu.pas
+++ b/compiler/avr/aasmcpu.pas
@@ -209,14 +209,14 @@ implementation
function taicpu.spilling_get_operation_type(opnr: longint): topertype;
begin
- result := operand_read;
+ result:=operand_read;
case opcode of
- A_CP,A_CPC,A_CPI :
+ A_CP,A_CPC,A_CPI,A_PUSH :
;
else
begin
- if opnr=ops-1 then
- result := operand_write;
+ if opnr=0 then
+ result:=operand_write;
end;
end;
end;
@@ -226,9 +226,15 @@ implementation
begin
case getregtype(r) of
R_INTREGISTER :
- result:=taicpu.op_ref_reg(A_LD,ref,r);
+ if ref.offset<>0 then
+ result:=taicpu.op_reg_ref(A_LDD,r,ref)
+ else
+ result:=taicpu.op_reg_ref(A_LD,r,ref);
R_ADDRESSREGISTER :
- result:=taicpu.op_ref_reg(A_LD,ref,r);
+ if ref.offset<>0 then
+ result:=taicpu.op_reg_ref(A_LDD,r,ref)
+ else
+ result:=taicpu.op_reg_ref(A_LD,r,ref);
else
internalerror(200401041);
end;
@@ -239,9 +245,15 @@ implementation
begin
case getregtype(r) of
R_INTREGISTER :
- result:=taicpu.op_reg_ref(A_ST,r,ref);
+ if ref.offset<>0 then
+ result:=taicpu.op_ref_reg(A_STD,ref,r)
+ else
+ result:=taicpu.op_ref_reg(A_ST,ref,r);
R_ADDRESSREGISTER :
- result:=taicpu.op_reg_ref(A_ST,r,ref);
+ if ref.offset<>0 then
+ result:=taicpu.op_ref_reg(A_STD,ref,r)
+ else
+ result:=taicpu.op_ref_reg(A_ST,ref,r);
else
internalerror(200401041);
end;
diff --git a/compiler/avr/agavrgas.pas b/compiler/avr/agavrgas.pas
index b73e7b4583..74b95429de 100644
--- a/compiler/avr/agavrgas.pas
+++ b/compiler/avr/agavrgas.pas
@@ -29,13 +29,18 @@ unit agavrgas;
interface
uses
+ globtype,
aasmtai,aasmdata,
aggas,
cpubase;
type
+
+ { TAVRGNUAssembler }
+
TAVRGNUAssembler=class(TGNUassembler)
constructor create(smart: boolean); override;
+ function MakeCmdLine: TCmdStr; override;
end;
TAVRInstrWriter=class(TCPUInstrWriter)
@@ -51,6 +56,7 @@ unit agavrgas;
assemble,
aasmcpu,
itcpugas,
+ cpuinfo,
cgbase,cgutils;
{****************************************************************************}
@@ -68,69 +74,102 @@ unit agavrgas;
{ Helper routines for Instruction Writer }
{****************************************************************************}
- function getreferencestring(var ref : treference) : string;
- var
- s : string;
- begin
- with ref do
- begin
-{$ifdef extdebug}
- // if base=NR_NO then
- // internalerror(200308292);
-
- // if ((index<>NR_NO) or (shiftmode<>SM_None)) and ((offset<>0) or (symbol<>nil)) then
- // internalerror(200308293);
-{$endif extdebug}
-
- if assigned(symbol) then
- begin
- s:=symbol.name;
- if offset<0 then
- s:=s+tostr(offset)
- else if offset>0 then
- s:=s+'+'+tostr(offset);
- end
- else
- begin
- s:=gas_regname(base);
- end;
- end;
- getreferencestring:=s;
- end;
+ Procedure TAVRInstrWriter.WriteInstruction(hp : tai);
+
+ function getreferencestring(var ref : treference) : string;
+ var
+ s : string;
+ begin
+ with ref do
+ begin
+ {$ifdef extdebug}
+ // if base=NR_NO then
+ // internalerror(200308292);
+
+ // if ((index<>NR_NO) or (shiftmode<>SM_None)) and ((offset<>0) or (symbol<>nil)) then
+ // internalerror(200308293);
+ {$endif extdebug}
+ if index<>NR_NO then
+ internalerror(2011021701)
+ else if base<>NR_NO then
+ begin
+ if addressmode=AM_PREDRECEMENT then
+ s:='-'
+ else
+ s:='';
+ case base of
+ NR_R26:
+ s:=s+'X';
+ NR_R28:
+ s:=s+'Y';
+ NR_R30:
+ s:=s+'Z';
+ else
+ s:=gas_regname(base);
+ end;
+ if addressmode=AM_POSTINCREMENT then
+ s:=s+'+';
+
+ if offset>0 then
+ s:=s+'+'+tostr(offset)
+ else if offset<0 then
+ s:=s+tostr(offset)
+ end
+ else if assigned(symbol) or (offset<>0) then
+ begin
+ if assigned(symbol) then
+ s:=ReplaceForbiddenChars(symbol.name)
+ else
+ s:='';
+
+ if offset<0 then
+ s:=s+tostr(offset)
+ else if offset>0 then
+ s:=s+'+'+tostr(offset);
+ case refaddr of
+ addr_hi8:
+ s:='hi8('+s+')';
+ addr_lo8:
+ s:='lo8('+s+')';
+ else
+ s:='('+s+')';
+ end;
+ end;
+ end;
+ getreferencestring:=s;
+ end;
- function getopstr(const o:toper) : string;
- var
- hs : string;
- first : boolean;
- r : tsuperregister;
- begin
- case o.typ of
- top_reg:
- getopstr:=gas_regname(o.reg);
- top_const:
- getopstr:='#'+tostr(longint(o.val));
- top_ref:
- if o.ref^.refaddr=addr_full then
- begin
- hs:=o.ref^.symbol.name;
- if o.ref^.offset>0 then
- hs:=hs+'+'+tostr(o.ref^.offset)
- else
- if o.ref^.offset<0 then
- hs:=hs+tostr(o.ref^.offset);
- getopstr:=hs;
- end
+ function getopstr(const o:toper) : string;
+ var
+ hs : string;
+ first : boolean;
+ r : tsuperregister;
+ begin
+ case o.typ of
+ top_reg:
+ getopstr:=gas_regname(o.reg);
+ top_const:
+ getopstr:=tostr(longint(o.val));
+ top_ref:
+ if o.ref^.refaddr=addr_full then
+ begin
+ hs:=ReplaceForbiddenChars(o.ref^.symbol.name);
+ if o.ref^.offset>0 then
+ hs:=hs+'+'+tostr(o.ref^.offset)
+ else
+ if o.ref^.offset<0 then
+ hs:=hs+tostr(o.ref^.offset);
+ getopstr:=hs;
+ end
+ else
+ getopstr:=getreferencestring(o.ref^);
else
- getopstr:=getreferencestring(o.ref^);
- else
- internalerror(2002070604);
+ internalerror(2002070604);
+ end;
end;
- end;
-
- Procedure TAVRInstrWriter.WriteInstruction(hp : tai);
var op: TAsmOp;
s: string;
i: byte;
@@ -151,6 +190,12 @@ unit agavrgas;
end;
+ function TAVRGNUAssembler.MakeCmdLine: TCmdStr;
+ begin
+ result := '-mmcu='+lower(cputypestr[current_settings.cputype])+' '+inherited MakeCmdLine;
+ end;
+
+
const
as_arm_gas_info : tasminfo =
(
diff --git a/compiler/avr/aoptcpu.pas b/compiler/avr/aoptcpu.pas
index 18d74edd3c..90611a1e78 100644
--- a/compiler/avr/aoptcpu.pas
+++ b/compiler/avr/aoptcpu.pas
@@ -40,7 +40,7 @@ Type
Implementation
uses
- aasmbase,aasmcpu;
+ aasmbase,aasmcpu,cgbase;
function CanBeCond(p : tai) : boolean;
begin
@@ -53,8 +53,44 @@ Implementation
next1: tai;
begin
result := false;
+ case p.typ of
+ ait_instruction:
+ begin
+ case taicpu(p).opcode of
+ A_MOV:
+ begin
+ { fold
+ mov reg2,reg0
+ mov reg3,reg1
+ to
+ movw reg2,reg0
+ }
+ if (taicpu(p).ops=2) and
+ (taicpu(p).oper[0]^.typ = top_reg) and
+ (taicpu(p).oper[1]^.typ = top_reg) and
+ getnextinstruction(p,next1) and
+ (next1.typ = ait_instruction) and
+ (taicpu(next1).opcode = A_MOV) and
+ (taicpu(next1).ops=2) and
+ (taicpu(next1).oper[0]^.typ = top_reg) and
+ (taicpu(next1).oper[1]^.typ = top_reg) and
+ (getsupreg(taicpu(next1).oper[0]^.reg)=getsupreg(taicpu(p).oper[0]^.reg)+1) and
+ ((getsupreg(taicpu(p).oper[0]^.reg) mod 2)=0) and
+ ((getsupreg(taicpu(p).oper[1]^.reg) mod 2)=0) and
+ (getsupreg(taicpu(next1).oper[1]^.reg)=getsupreg(taicpu(p).oper[1]^.reg)+1) then
+ begin
+ taicpu(p).opcode:=A_MOVW;
+ asml.remove(next1);
+ next1.free;
+ result := true;
+ end;
+ end;
+ end;
+ end;
+ end;
end;
+
procedure TCpuAsmOptimizer.PeepHoleOptPass2;
begin
end;
diff --git a/compiler/avr/cgcpu.pas b/compiler/avr/cgcpu.pas
index be57425737..52cbd66b1c 100644
--- a/compiler/avr/cgcpu.pas
+++ b/compiler/avr/cgcpu.pas
@@ -34,7 +34,6 @@ unit cgcpu;
parabase,
cpubase,cpuinfo,node,cg64f32,rgcpu;
-
type
{ tcgavr }
@@ -46,6 +45,7 @@ unit cgcpu;
procedure done_register_allocators;override;
function getintregister(list:TAsmList;size:Tcgsize):Tregister;override;
+ function getaddressregister(list:TAsmList):TRegister;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;
@@ -81,32 +81,29 @@ unit cgcpu;
procedure a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);override;
procedure g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);override;
- procedure g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint);override;
procedure g_concatcopy_move(list : TAsmList;const source,dest : treference;len : aint);
- procedure g_concatcopy_internal(list : TAsmList;const source,dest : treference;len : aint;aligned : boolean);
procedure g_overflowcheck(list: TAsmList; const l: tlocation; def: tdef); override;
-// procedure g_save_registers(list : TAsmList);override;
-// procedure g_restore_registers(list : TAsmList);override;
+ procedure g_save_registers(list : TAsmList);override;
+ procedure g_restore_registers(list : TAsmList);override;
procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
procedure fixref(list : TAsmList;var ref : treference);
- function normalize_ref(list:TAsmList;ref: treference):treference;
+ function normalize_ref(list : TAsmList;ref : treference;
+ tmpreg : tregister) : treference;
procedure g_intf_wrapper(list: TAsmList; procdef: tprocdef; const labelname: string; ioffset: longint);override;
procedure emit_mov(list: TAsmList;reg2: tregister; reg1: tregister);
procedure a_adjust_sp(list: TAsmList; value: longint);
+ function GetLoad(const ref : treference) : tasmop;
+ function GetStore(const ref: treference): tasmop;
end;
tcg64favr = class(tcg64f32)
procedure a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);override;
procedure a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);override;
- procedure a_op64_const_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);override;
- procedure a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);override;
- procedure a_op64_const_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
- procedure a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);override;
end;
procedure create_codegen;
@@ -130,18 +127,19 @@ unit cgcpu;
begin
inherited init_register_allocators;
rg[R_INTREGISTER]:=trgintcpu.create(R_INTREGISTER,R_SUBWHOLE,
- [RS_R0,RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,
+ [RS_R8,RS_R9,
RS_R10,RS_R11,RS_R12,RS_R13,RS_R14,RS_R15,RS_R16,RS_R17,RS_R18,RS_R19,
- RS_R20,RS_R21,RS_R22,RS_R23,RS_R24,RS_R25],first_int_imreg,[]);
- rg[R_ADDRESSREGISTER]:=trgintcpu.create(R_ADDRESSREGISTER,R_SUBWHOLE,
- [RS_R26,RS_R30],first_int_imreg,[]);
+ RS_R20,RS_R21,RS_R22,RS_R23,RS_R24,RS_R25,
+ RS_R2,RS_R3,RS_R4,RS_R5,RS_R6,RS_R7],first_int_imreg,[]);
+ { rg[R_ADDRESSREGISTER]:=trgintcpu.create(R_ADDRESSREGISTER,R_SUBWHOLE,
+ [RS_R26,RS_R30],first_int_imreg,[]); }
end;
procedure tcgavr.done_register_allocators;
begin
rg[R_INTREGISTER].free;
- rg[R_ADDRESSREGISTER].free;
+ // rg[R_ADDRESSREGISTER].free;
inherited done_register_allocators;
end;
@@ -190,6 +188,12 @@ unit cgcpu;
end;
+ function tcgavr.getaddressregister(list: TAsmList): TRegister;
+ begin
+ Result:=getintregister(list,OS_ADDR);
+ end;
+
+
procedure tcgavr.a_load_const_cgpara(list : TAsmList;size : tcgsize;a : aint;const paraloc : TCGPara);
var
ref: treference;
@@ -375,16 +379,16 @@ unit cgcpu;
procedure tcgavr.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister);
var
+ countreg,
tmpreg: tregister;
i : integer;
instr : taicpu;
+ paraloc1,paraloc2,paraloc3 : TCGPara;
+ l1,l2 : tasmlabel;
begin
case op of
OP_ADD:
begin
- if src<>dst then
- a_load_reg_reg(list,size,size,src,dst);
-
list.concat(taicpu.op_reg_reg(A_ADD,dst,src));
if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
begin
@@ -400,9 +404,6 @@ unit cgcpu;
OP_SUB:
begin
- if src<>dst then
- a_load_reg_reg(list,size,size,src,dst);
-
list.concat(taicpu.op_reg_reg(A_SUB,dst,src));
if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
begin
@@ -432,7 +433,7 @@ unit cgcpu;
tmpreg:=GetNextReg(dst);
for i:=2 to tcgsize2size[size] do
begin
- list.concat(taicpu.op_const_reg(A_SBCI,-1,dst));
+ list.concat(taicpu.op_reg_const(A_SBCI,dst,-1));
tmpreg:=GetNextReg(tmpreg);
end;
end
@@ -456,6 +457,29 @@ unit cgcpu;
begin
if size in [OS_8,OS_S8] then
list.concat(taicpu.op_reg_reg(topcg2asmop[op],dst,src))
+ else if size=OS_16 then
+ begin
+ paraloc1.init;
+ paraloc2.init;
+ paraloc3.init;
+ paramanager.getintparaloc(pocall_default,1,paraloc1);
+ paramanager.getintparaloc(pocall_default,2,paraloc2);
+ paramanager.getintparaloc(pocall_default,3,paraloc3);
+ a_load_const_cgpara(list,OS_8,0,paraloc3);
+ a_load_reg_cgpara(list,OS_16,src,paraloc2);
+ a_load_reg_cgpara(list,OS_16,dst,paraloc1);
+ paramanager.freecgpara(list,paraloc3);
+ paramanager.freecgpara(list,paraloc2);
+ paramanager.freecgpara(list,paraloc1);
+ alloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+ a_call_name(list,'FPC_MUL_WORD',false);
+ dealloccpuregisters(list,R_INTREGISTER,paramanager.get_volatile_registers_int(pocall_default));
+ cg.a_reg_alloc(list,NR_FUNCTION_RESULT_REG);
+ cg.a_load_reg_reg(list,OS_16,OS_16,NR_FUNCTION_RESULT_REG,dst);
+ paraloc3.done;
+ paraloc2.done;
+ paraloc1.done;
+ end
else
internalerror(2011022002);
end;
@@ -467,14 +491,73 @@ unit cgcpu;
OP_SHR,OP_SHL,OP_SAR,OP_ROL,OP_ROR:
begin
- {!!!!!!!}
+ current_asmdata.getjumplabel(l1);
+ current_asmdata.getjumplabel(l2);
+ countreg:=getintregister(list,OS_8);
+ a_load_reg_reg(list,size,OS_8,src,countreg);
+ list.concat(taicpu.op_reg_const(A_CP,countreg,0));
+ a_jmp_flags(list,F_EQ,l2);
+ cg.a_label(list,l1);
+ case op of
+ OP_SHR:
+ list.concat(taicpu.op_reg(A_LSR,GetOffsetReg(dst,tcgsize2size[size]-1)));
+ OP_SHL:
+ list.concat(taicpu.op_reg(A_LSL,dst));
+ OP_SAR:
+ list.concat(taicpu.op_reg(A_ASR,GetOffsetReg(dst,tcgsize2size[size]-1)));
+ OP_ROR:
+ begin
+ { load carry? }
+ if not(size in [OS_8,OS_S8]) then
+ begin
+ list.concat(taicpu.op_none(A_CLC));
+ list.concat(taicpu.op_reg_const(A_SBRC,src,0));
+ list.concat(taicpu.op_none(A_SEC));
+ end;
+ list.concat(taicpu.op_reg(A_ROR,GetOffsetReg(dst,tcgsize2size[size]-1)));
+ end;
+ OP_ROL:
+ begin
+ { load carry? }
+ if not(size in [OS_8,OS_S8]) then
+ begin
+ list.concat(taicpu.op_none(A_CLC));
+ list.concat(taicpu.op_reg_const(A_SBRC,GetOffsetReg(dst,tcgsize2size[size]-1),7));
+ list.concat(taicpu.op_none(A_SEC));
+ end;
+ list.concat(taicpu.op_reg(A_ROL,dst))
+ end;
+ else
+ internalerror(2011030901);
+ end;
+ if size in [OS_S16,OS_16,OS_S32,OS_32,OS_S64,OS_64] then
+ begin
+ for i:=2 to tcgsize2size[size] do
+ begin
+ case op of
+ OP_ROR,
+ OP_SHR:
+ list.concat(taicpu.op_reg(A_ROR,GetOffsetReg(dst,tcgsize2size[size]-i)));
+ OP_ROL,
+ OP_SHL:
+ list.concat(taicpu.op_reg(A_ROL,GetOffsetReg(dst,i-1)));
+ OP_SAR:
+ list.concat(taicpu.op_reg(A_ROR,GetOffsetReg(dst,tcgsize2size[size]-i)));
+ else
+ internalerror(2011030902);
+ end;
+ end;
+ end;
+
+ a_op_const_reg(list,OP_SUB,OS_8,1,countreg);
+ a_jmp_flags(list,F_NE,l1);
+ // keep registers alive
+ list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
+ cg.a_label(list,l2);
end;
OP_AND,OP_OR,OP_XOR:
begin
- if src<>dst then
- a_load_reg_reg(list,size,size,src,dst);
-
for i:=1 to tcgsize2size[size] do
begin
list.concat(taicpu.op_reg_reg(topcg2asmop[op],dst,src));
@@ -482,7 +565,7 @@ unit cgcpu;
src:=GetNextReg(src);
end;
end;
- else
+ else
internalerror(2011022004);
end;
end;
@@ -498,7 +581,11 @@ unit cgcpu;
shift:=0;
for i:=1 to tcgsize2size[size] do
begin
- list.concat(taicpu.op_reg_const(A_LDI,reg,(qword(a) and mask) shr shift));
+ if ((qword(a) and mask) shr shift)=0 then
+ emit_mov(list,reg,NR_R1)
+ else
+ list.concat(taicpu.op_reg_const(A_LDI,reg,(qword(a) and mask) shr shift));
+
mask:=mask shl 8;
inc(shift,8);
reg:=GetNextReg(reg);
@@ -506,14 +593,11 @@ unit cgcpu;
end;
- function tcgavr.normalize_ref(list:TAsmList;ref: treference):treference;
+ function tcgavr.normalize_ref(list:TAsmList;ref: treference;tmpreg : tregister) : treference;
var
- tmpreg : tregister;
tmpref : treference;
l : tasmlabel;
begin
- tmpreg:=NR_NO;
-
Result:=ref;
if ref.addressmode<>AM_UNCHANGED then
@@ -530,14 +614,14 @@ unit cgcpu;
end;
if assigned(ref.symbol) or (ref.offset<>0) then
begin
- tmpreg:=getaddressregister(list);
reference_reset(tmpref,0);
tmpref.symbol:=ref.symbol;
- tmpref.offset:=lo(word(ref.offset));
+ tmpref.offset:=ref.offset;
tmpref.refaddr:=addr_lo8;
+ getcpuregister(list,tmpreg);
list.concat(taicpu.op_reg_ref(A_LDI,tmpreg,tmpref));
- tmpref.offset:=hi(word(ref.offset));
tmpref.refaddr:=addr_hi8;
+ getcpuregister(list,GetNextReg(tmpreg));
list.concat(taicpu.op_reg_ref(A_LDI,GetNextReg(tmpreg),tmpref));
if (ref.base<>NR_NO) then
begin
@@ -546,20 +630,42 @@ unit cgcpu;
end;
if (ref.index<>NR_NO) then
begin
- list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.base));
- list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.base)));
+ list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.index));
+ list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.index)));
end;
+ ref.symbol:=nil;
+ ref.offset:=0;
ref.base:=tmpreg;
ref.index:=NR_NO;
end
else if (ref.base<>NR_NO) and (ref.index<>NR_NO) then
begin
- tmpreg:=getaddressregister(list);
- list.concat(taicpu.op_reg_reg(A_MOVW,tmpreg,ref.index));
+ getcpuregister(list,tmpreg);
+ emit_mov(list,tmpreg,ref.index);
+ getcpuregister(list,GetNextReg(tmpreg));
+ emit_mov(list,GetNextReg(tmpreg),GetNextReg(ref.index));
list.concat(taicpu.op_reg_reg(A_ADD,tmpreg,ref.base));
list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.base)));
ref.base:=tmpreg;
ref.index:=NR_NO;
+ end
+ else if (ref.base<>NR_NO) then
+ begin
+ getcpuregister(list,tmpreg);
+ emit_mov(list,tmpreg,ref.base);
+ getcpuregister(list,GetNextReg(tmpreg));
+ emit_mov(list,GetNextReg(tmpreg),GetNextReg(ref.base));
+ ref.base:=tmpreg;
+ ref.index:=NR_NO;
+ end
+ else if (ref.index<>NR_NO) then
+ begin
+ getcpuregister(list,tmpreg);
+ emit_mov(list,tmpreg,ref.index);
+ getcpuregister(list,GetNextReg(tmpreg));
+ emit_mov(list,GetNextReg(tmpreg),GetNextReg(ref.index));
+ ref.base:=tmpreg;
+ ref.index:=NR_NO;
end;
Result:=ref;
end;
@@ -571,8 +677,23 @@ unit cgcpu;
conv_done: boolean;
tmpreg : tregister;
i : integer;
+ QuickRef : Boolean;
begin
- href:=normalize_ref(list,Ref);
+ QuickRef:=false;
+ if not((Ref.addressmode=AM_UNCHANGED) and
+ (Ref.symbol=nil) and
+ ((Ref.base=NR_R28) or
+ (Ref.base=NR_R29)) and
+ (Ref.Index=NR_No) and
+ (Ref.Offset in [0..64-tcgsize2size[tosize]])) and
+ not((Ref.Base=NR_NO) and (Ref.Index=NR_NO)) then
+ href:=normalize_ref(list,Ref,NR_R30)
+ else
+ begin
+ QuickRef:=true;
+ href:=Ref;
+ end;
+
if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
internalerror(2011021307);
@@ -585,109 +706,109 @@ unit cgcpu;
case fromsize of
OS_8:
begin
- if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
+ if not(QuickRef) and (tcgsize2size[tosize]>1) then
href.addressmode:=AM_POSTINCREMENT;
- list.concat(taicpu.op_ref_reg(A_ST,href,reg));
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
for i:=2 to tcgsize2size[tosize] do
begin
- if (href.offset<>0) or assigned(href.symbol) then
+ if QuickRef then
inc(href.offset);
- if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+ if not(QuickRef) and (i<tcgsize2size[fromsize]) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
- list.concat(taicpu.op_ref_reg(A_ST,href,NR_R1));
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,NR_R1));
end;
end;
OS_S8:
begin
- if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
+ if not(QuickRef) and (tcgsize2size[tosize]>1) then
href.addressmode:=AM_POSTINCREMENT;
- list.concat(taicpu.op_ref_reg(A_ST,href,reg));
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
if tcgsize2size[tosize]>1 then
begin
tmpreg:=getintregister(list,OS_8);
list.concat(taicpu.op_reg(A_CLR,tmpreg));
- list.concat(taicpu.op_reg_const(A_SBIC,reg,7));
+ list.concat(taicpu.op_reg_const(A_SBRC,reg,7));
list.concat(taicpu.op_reg(A_COM,tmpreg));
for i:=2 to tcgsize2size[tosize] do
begin
- if (href.offset<>0) or assigned(href.symbol) then
+ if QuickRef then
inc(href.offset);
- if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+ if not(QuickRef) and (i<tcgsize2size[fromsize]) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
- list.concat(taicpu.op_ref_reg(A_ST,href,tmpreg));
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,tmpreg));
end;
end;
end;
OS_16:
begin
- if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
+ if not(QuickRef) and (tcgsize2size[tosize]>1) then
href.addressmode:=AM_POSTINCREMENT;
- list.concat(taicpu.op_ref_reg(A_ST,href,reg));
- if (href.offset<>0) or assigned(href.symbol) then
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
+ if QuickRef then
inc(href.offset)
- else if (href.base<>NR_NO) and (tcgsize2size[fromsize]>2) then
+ else if not(QuickRef) and (tcgsize2size[fromsize]>2) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
reg:=GetNextReg(reg);
- list.concat(taicpu.op_ref_reg(A_ST,href,reg));
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
for i:=3 to tcgsize2size[tosize] do
begin
- if (href.offset<>0) or assigned(href.symbol) then
+ if QuickRef then
inc(href.offset);
- if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+ if not(QuickRef) and (i<tcgsize2size[fromsize]) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
- list.concat(taicpu.op_ref_reg(A_ST,href,NR_R1));
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,NR_R1));
end;
end;
OS_S16:
begin
- if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
+ if not(QuickRef) and (tcgsize2size[tosize]>1) then
href.addressmode:=AM_POSTINCREMENT;
- list.concat(taicpu.op_ref_reg(A_ST,href,reg));
- if (href.offset<>0) or assigned(href.symbol) then
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
+ if QuickRef then
inc(href.offset)
- else if (href.base<>NR_NO) and (tcgsize2size[fromsize]>2) then
+ else if not(QuickRef) and (tcgsize2size[fromsize]>2) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
reg:=GetNextReg(reg);
- list.concat(taicpu.op_ref_reg(A_ST,href,reg));
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
if tcgsize2size[tosize]>2 then
begin
tmpreg:=getintregister(list,OS_8);
list.concat(taicpu.op_reg(A_CLR,tmpreg));
- list.concat(taicpu.op_reg_const(A_SBIC,reg,7));
+ list.concat(taicpu.op_reg_const(A_SBRC,reg,7));
list.concat(taicpu.op_reg(A_COM,tmpreg));
for i:=3 to tcgsize2size[tosize] do
begin
- if (href.offset<>0) or assigned(href.symbol) then
+ if QuickRef then
inc(href.offset);
- if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+ if not(QuickRef) and (i<tcgsize2size[fromsize]) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
- list.concat(taicpu.op_ref_reg(A_ST,href,tmpreg));
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,tmpreg));
end;
end;
end;
@@ -699,19 +820,25 @@ unit cgcpu;
begin
for i:=1 to tcgsize2size[fromsize] do
begin
- if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
+ if not(QuickRef) and (i<tcgsize2size[fromsize]) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
- list.concat(taicpu.op_ref_reg(A_ST,href,reg));
+ list.concat(taicpu.op_ref_reg(GetStore(href),href,reg));
- if (href.offset<>0) or assigned(href.symbol) then
+ if QuickRef then
inc(href.offset);
reg:=GetNextReg(reg);
end;
end;
+
+ if not(QuickRef) then
+ begin
+ ungetcpuregister(list,href.base);
+ ungetcpuregister(list,GetNextReg(href.base));
+ end;
end;
@@ -722,8 +849,23 @@ unit cgcpu;
conv_done: boolean;
tmpreg : tregister;
i : integer;
+ QuickRef : boolean;
begin
- href:=normalize_ref(list,Ref);
+ QuickRef:=false;
+ if not((Ref.addressmode=AM_UNCHANGED) and
+ (Ref.symbol=nil) and
+ ((Ref.base=NR_R28) or
+ (Ref.base=NR_R29)) and
+ (Ref.Index=NR_No) and
+ (Ref.Offset in [0..64-tcgsize2size[fromsize]])) and
+ not((Ref.Base=NR_NO) and (Ref.Index=NR_NO)) then
+ href:=normalize_ref(list,Ref,NR_R30)
+ else
+ begin
+ QuickRef:=true;
+ href:=Ref;
+ end;
+
if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
internalerror(2011021307);
@@ -736,7 +878,7 @@ unit cgcpu;
case fromsize of
OS_8:
begin
- list.concat(taicpu.op_reg_ref(A_LD,reg,href));
+ list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
for i:=2 to tcgsize2size[tosize] do
begin
reg:=GetNextReg(reg);
@@ -745,14 +887,14 @@ unit cgcpu;
end;
OS_S8:
begin
- list.concat(taicpu.op_reg_ref(A_LD,reg,href));
+ list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
tmpreg:=reg;
if tcgsize2size[tosize]>1 then
begin
reg:=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_const(A_SBRC,tmpreg,7));
list.concat(taicpu.op_reg(A_COM,reg));
tmpreg:=reg;
for i:=3 to tcgsize2size[tosize] do
@@ -764,16 +906,16 @@ unit cgcpu;
end;
OS_16:
begin
- if href.base<>NR_NO then
+ if not(QuickRef) then
href.addressmode:=AM_POSTINCREMENT;
- list.concat(taicpu.op_reg_ref(A_LD,reg,href));
+ list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
- if (href.offset<>0) or assigned(href.symbol) then
+ if QuickRef then
inc(href.offset);
href.addressmode:=AM_UNCHANGED;
reg:=GetNextReg(reg);
- list.concat(taicpu.op_reg_ref(A_LD,reg,href));
+ list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
for i:=3 to tcgsize2size[tosize] do
begin
@@ -783,20 +925,20 @@ unit cgcpu;
end;
OS_S16:
begin
- if href.base<>NR_NO then
+ if not(QuickRef) then
href.addressmode:=AM_POSTINCREMENT;
- list.concat(taicpu.op_reg_ref(A_LD,reg,href));
- if (href.offset<>0) or assigned(href.symbol) then
+ list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
+ if QuickRef then
inc(href.offset);
href.addressmode:=AM_UNCHANGED;
reg:=GetNextReg(reg);
- list.concat(taicpu.op_reg_ref(A_LD,reg,href));
+ list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
tmpreg:=reg;
reg:=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_const(A_SBRC,tmpreg,7));
list.concat(taicpu.op_reg(A_COM,reg));
tmpreg:=reg;
for i:=4 to tcgsize2size[tosize] do
@@ -813,19 +955,25 @@ unit cgcpu;
begin
for i:=1 to tcgsize2size[fromsize] do
begin
- if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
- href.addressmode:=AM_POSTINCREMENT
- else
- href.addressmode:=AM_UNCHANGED;
+ if not(QuickRef) and (i<tcgsize2size[fromsize]) then
+ href.addressmode:=AM_POSTINCREMENT
+ else
+ href.addressmode:=AM_UNCHANGED;
- list.concat(taicpu.op_reg_ref(A_LD,reg,href));
+ list.concat(taicpu.op_reg_ref(GetLoad(href),reg,href));
- if (href.offset<>0) or assigned(href.symbol) then
+ if QuickRef then
inc(href.offset);
reg:=GetNextReg(reg);
end;
end;
+
+ if not(QuickRef) then
+ begin
+ ungetcpuregister(list,href.base);
+ ungetcpuregister(list,GetNextReg(href.base));
+ end;
end;
@@ -861,7 +1009,7 @@ unit cgcpu;
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_const(A_SBRC,reg1,7));
list.concat(taicpu.op_reg(A_COM,reg2));
tmpreg:=reg2;
for i:=3 to tcgsize2size[tosize] do
@@ -895,7 +1043,7 @@ unit cgcpu;
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_const(A_SBRC,reg1,7));
list.concat(taicpu.op_reg(A_COM,reg2));
tmpreg:=reg2;
for i:=4 to tcgsize2size[tosize] do
@@ -921,22 +1069,116 @@ unit cgcpu;
{ comparison operations }
- procedure tcgavr.a_cmp_const_reg_label(list : TAsmList;size : tcgsize;cmp_op : topcmp;a : aint;reg : tregister;
- l : tasmlabel);
+ procedure tcgavr.a_cmp_const_reg_label(list : TAsmList;size : tcgsize;
+ cmp_op : topcmp;a : aint;reg : tregister;l : tasmlabel);
+ var
+ swapped : boolean;
+ tmpreg : tregister;
+ i : byte;
begin
- internalerror(2011021311);
+ if a=0 then
+ begin
+ { swap parameters? }
+ case cmp_op of
+ OC_GT:
+ begin
+ swapped:=true;
+ cmp_op:=OC_LT;
+ end;
+ OC_LTE:
+ begin
+ swapped:=true;
+ cmp_op:=OC_GTE;
+ end;
+ OC_BE:
+ begin
+ swapped:=true;
+ cmp_op:=OC_AE;
+ end;
+ OC_A:
+ begin
+ swapped:=true;
+ cmp_op:=OC_A;
+ end;
+ end;
+
+ if swapped then
+ list.concat(taicpu.op_reg_reg(A_CP,reg,NR_R1))
+ else
+ list.concat(taicpu.op_reg_reg(A_CP,NR_R1,reg));
+
+ for i:=2 to tcgsize2size[size] do
+ begin
+ reg:=GetNextReg(reg);
+ if swapped then
+ list.concat(taicpu.op_reg_reg(A_CPC,reg,NR_R1))
+ else
+ list.concat(taicpu.op_reg_reg(A_CPC,NR_R1,reg));
+ end;
+
+ a_jmp_cond(list,cmp_op,l);
+ end
+ else
+ inherited a_cmp_const_reg_label(list,size,cmp_op,a,reg,l);
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);
+ var
+ swapped : boolean;
+ tmpreg : tregister;
+ i : byte;
begin
- internalerror(2011021312);
+ { swap parameters? }
+ case cmp_op of
+ OC_GT:
+ begin
+ swapped:=true;
+ cmp_op:=OC_LT;
+ end;
+ OC_LTE:
+ begin
+ swapped:=true;
+ cmp_op:=OC_GTE;
+ end;
+ OC_BE:
+ begin
+ swapped:=true;
+ cmp_op:=OC_AE;
+ end;
+ OC_A:
+ begin
+ swapped:=true;
+ cmp_op:=OC_A;
+ end;
+ end;
+ if swapped then
+ begin
+ tmpreg:=reg1;
+ reg1:=reg2;
+ reg2:=tmpreg;
+ end;
+ list.concat(taicpu.op_reg_reg(A_CP,reg1,reg2));
+
+ for i:=2 to tcgsize2size[size] do
+ begin
+ reg1:=GetNextReg(reg1);
+ reg2:=GetNextReg(reg2);
+ list.concat(taicpu.op_reg_reg(A_CPC,reg1,reg2));
+ end;
+
+ a_jmp_cond(list,cmp_op,l);
end;
procedure tcgavr.a_jmp_name(list : TAsmList;const s : string);
+ var
+ ai : taicpu;
begin
- internalerror(2011021313);
+ ai:=taicpu.op_sym(A_JMP,current_asmdata.RefAsmSymbol(s));
+ ai.is_jmp:=true;
+ list.concat(ai);
end;
@@ -961,10 +1203,31 @@ unit cgcpu;
procedure tcgavr.g_flags2reg(list: TAsmList; size: TCgSize; const f: TResFlags; reg: TRegister);
+ var
+ l : TAsmLabel;
+ tmpflags : TResFlags;
begin
- internalerror(2011021316);
+ current_asmdata.getjumplabel(l);
+ {
+ if flags_to_cond(f) then
+ begin
+ tmpflags:=f;
+ inverse_flags(tmpflags);
+ list.concat(taicpu.op_reg(A_CLR,reg));
+ a_jmp_flags(list,tmpflags,l);
+ list.concat(taicpu.op_reg_const(A_LDI,reg,1));
+ end
+ else
+ }
+ begin
+ list.concat(taicpu.op_reg_const(A_LDI,reg,1));
+ a_jmp_flags(list,f,l);
+ list.concat(taicpu.op_reg(A_CLR,reg));
+ end;
+ cg.a_label(list,l);
end;
+
procedure tcgavr.a_adjust_sp(list : TAsmList; value : longint);
var
i : integer;
@@ -1006,6 +1269,29 @@ unit cgcpu;
end;
end;
+
+ function tcgavr.GetLoad(const ref: treference) : tasmop;
+ begin
+ if (ref.base=NR_NO) and (ref.index=NR_NO) then
+ result:=A_LDS
+ else if (ref.base<>NR_NO) and (ref.offset<>0) then
+ result:=A_LDD
+ else
+ result:=A_LD;
+ end;
+
+
+ function tcgavr.GetStore(const ref: treference) : tasmop;
+ begin
+ if (ref.base=NR_NO) and (ref.index=NR_NO) then
+ result:=A_STS
+ else if (ref.base<>NR_NO) and (ref.offset<>0) then
+ result:=A_STD
+ else
+ result:=A_ST;
+ end;
+
+
procedure tcgavr.g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);
var
regs : tcpuregisterset;
@@ -1050,12 +1336,12 @@ unit cgcpu;
begin
LocalSize:=current_procinfo.calc_stackframe_size;
a_adjust_sp(list,LocalSize);
+ regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
for reg:=RS_R0 to RS_R31 do
if reg in regs then
list.concat(taicpu.op_reg(A_POP,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
- regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
end
else
{ the framepointer cannot be omitted on avr because sp
@@ -1068,8 +1354,47 @@ unit cgcpu;
procedure tcgavr.a_loadaddr_ref_reg(list : TAsmList;const ref : treference;r : tregister);
+ var
+ tmpref : treference;
begin
- //!!!!
+ if ref.addressmode<>AM_UNCHANGED then
+ internalerror(2011021701);
+
+ if assigned(ref.symbol) or (ref.offset<>0) then
+ begin
+ reference_reset(tmpref,0);
+ tmpref.symbol:=ref.symbol;
+ tmpref.offset:=ref.offset;
+ tmpref.refaddr:=addr_lo8;
+ list.concat(taicpu.op_reg_ref(A_LDI,r,tmpref));
+ tmpref.refaddr:=addr_hi8;
+ list.concat(taicpu.op_reg_ref(A_LDI,GetNextReg(r),tmpref));
+ if (ref.base<>NR_NO) then
+ begin
+ list.concat(taicpu.op_reg_reg(A_ADD,r,ref.base));
+ list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(r),GetNextReg(ref.base)));
+ end;
+ if (ref.index<>NR_NO) then
+ begin
+ list.concat(taicpu.op_reg_reg(A_ADD,r,ref.index));
+ list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(r),GetNextReg(ref.index)));
+ end;
+ end
+ else if (ref.base<>NR_NO)then
+ begin
+ emit_mov(list,r,ref.base);
+ emit_mov(list,GetNextReg(r),GetNextReg(ref.base));
+ if (ref.index<>NR_NO) then
+ begin
+ list.concat(taicpu.op_reg_reg(A_ADD,r,ref.index));
+ list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(r),GetNextReg(ref.index)));
+ end;
+ end
+ else if (ref.index<>NR_NO) then
+ begin
+ emit_mov(list,r,ref.index);
+ emit_mov(list,GetNextReg(r),GetNextReg(ref.index));
+ end;
end;
@@ -1104,17 +1429,6 @@ unit cgcpu;
end;
- procedure tcgavr.g_concatcopy_internal(list : TAsmList;const source,dest : treference;len : aint;aligned : boolean);
- begin
- internalerror(2011021321);
- end;
-
- procedure tcgavr.g_concatcopy_unaligned(list : TAsmList;const source,dest : treference;len : aint);
- begin
- g_concatcopy_internal(list,source,dest,len,false);
- end;
-
-
procedure tcgavr.g_concatcopy(list : TAsmList;const source,dest : treference;len : aint);
var
countreg,tmpreg : tregister;
@@ -1122,11 +1436,19 @@ unit cgcpu;
copysize,countregsize : tcgsize;
l : TAsmLabel;
i : longint;
+ SrcQuickRef, DestQuickRef : Boolean;
begin
- current_asmdata.getjumplabel(l);
if len>16 then
begin
- {!!!!!!! load refs!}
+ current_asmdata.getjumplabel(l);
+
+ reference_reset(srcref,0);
+ reference_reset(dstref,0);
+ srcref.base:=NR_R30;
+ srcref.addressmode:=AM_POSTINCREMENT;
+ dstref.base:=NR_R26;
+ dstref.addressmode:=AM_POSTINCREMENT;
+
copysize:=OS_8;
if len<256 then
countregsize:=OS_8
@@ -1136,38 +1458,99 @@ unit cgcpu;
internalerror(2011022007);
countreg:=getintregister(list,countregsize);
a_load_const_reg(list,countregsize,len,countreg);
+ a_loadaddr_ref_reg(list,source,NR_R30);
+ tmpreg:=getaddressregister(list);
+ a_loadaddr_ref_reg(list,dest,tmpreg);
+
+ { X is used for spilling code so we can load it
+ only by a push/pop sequence, this can be
+ optimized later on by the peephole optimizer
+ }
+ list.concat(taicpu.op_reg(A_PUSH,tmpreg));
+ list.concat(taicpu.op_reg(A_PUSH,GetNextReg(tmpreg)));
+ list.concat(taicpu.op_reg(A_POP,NR_R27));
+ list.concat(taicpu.op_reg(A_POP,NR_R26));
cg.a_label(list,l);
- tmpreg:=getintregister(list,copysize);
- list.concat(taicpu.op_reg_ref(A_LD,tmpreg,srcref));
- list.concat(taicpu.op_ref_reg(A_ST,dstref,tmpreg));
+ list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
+ list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
a_op_const_reg(list,OP_SUB,countregsize,1,countreg);
a_jmp_flags(list,F_NE,l);
+ // keep registers alive
+ list.concat(taicpu.op_reg_reg(A_MOV,countreg,countreg));
end
else
begin
+ SrcQuickRef:=false;
+ DestQuickRef:=false;
+ if not((source.addressmode=AM_UNCHANGED) and
+ (source.symbol=nil) and
+ ((source.base=NR_R28) or
+ (source.base=NR_R29)) and
+ (source.Index=NR_No) and
+ (source.Offset in [0..64-len])) and
+ not((source.Base=NR_NO) and (source.Index=NR_NO)) then
+ srcref:=normalize_ref(list,source,NR_R30)
+ else
+ begin
+ SrcQuickRef:=true;
+ srcref:=source;
+ end;
+
+ if not((dest.addressmode=AM_UNCHANGED) and
+ (dest.symbol=nil) and
+ ((dest.base=NR_R28) or
+ (dest.base=NR_R29)) and
+ (dest.Index=NR_No) and
+ (dest.Offset in [0..64-len])) and
+ not((dest.Base=NR_NO) and (dest.Index=NR_NO)) then
+ begin
+ if not(SrcQuickRef) then
+ begin
+ tmpreg:=getaddressregister(list);
+ dstref:=normalize_ref(list,dest,tmpreg);
+
+ { X is used for spilling code so we can load it
+ only by a push/pop sequence, this can be
+ optimized later on by the peephole optimizer
+ }
+ list.concat(taicpu.op_reg(A_PUSH,tmpreg));
+ list.concat(taicpu.op_reg(A_PUSH,GetNextReg(tmpreg)));
+ list.concat(taicpu.op_reg(A_POP,NR_R27));
+ list.concat(taicpu.op_reg(A_POP,NR_R26));
+ end
+ else
+ dstref:=normalize_ref(list,dest,NR_R30);
+ end
+ else
+ begin
+ DestQuickRef:=true;
+ dstref:=dest;
+ end;
+
for i:=1 to len do
begin
- srcref:=normalize_ref(list,source);
- dstref:=normalize_ref(list,source);
- copysize:=OS_8;
- tmpreg:=getintregister(list,copysize);
- if (srcref.base<>NR_NO) and (i<len) then
+ if not(SrcQuickRef) and (i<len) then
srcref.addressmode:=AM_POSTINCREMENT
else
srcref.addressmode:=AM_UNCHANGED;
- if (dstref.base<>NR_NO) and (i<len) then
+
+ if not(DestQuickRef) and (i<len) then
dstref.addressmode:=AM_POSTINCREMENT
else
dstref.addressmode:=AM_UNCHANGED;
- list.concat(taicpu.op_reg_ref(A_LD,tmpreg,srcref));
- list.concat(taicpu.op_ref_reg(A_ST,dstref,tmpreg));
-
- if (dstref.offset<>0) or assigned(dstref.symbol) then
- inc(dstref.offset);
- if (srcref.offset<>0) or assigned(srcref.symbol) then
- inc(srcref.offset);
+ list.concat(taicpu.op_reg_ref(GetLoad(srcref),NR_R0,srcref));
+ list.concat(taicpu.op_ref_reg(GetStore(dstref),dstref,NR_R0));
+ if SrcQuickRef then
+ inc(srcref.offset);
+ if DestQuickRef then
+ inc(dstref.offset);
+ end;
+ if not(SrcQuickRef) then
+ begin
+ ungetcpuregister(list,srcref.base);
+ ungetcpuregister(list,GetNextReg(srcref.base));
end;
end;
end;
@@ -1198,11 +1581,24 @@ unit cgcpu;
end;
+ procedure tcgavr.g_save_registers(list: TAsmList);
+ begin
+ { this is done by the entry code }
+ end;
+
+
+ procedure tcgavr.g_restore_registers(list: TAsmList);
+ begin
+ { this is done by the exit code }
+ end;
+
+
procedure tcgavr.a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
var
ai : taicpu;
begin
- {!!!!!
+ { TODO : fix a_jmp_cond }
+ {
ai:=Taicpu.Op_sym(A_BRxx,l);
case cond of
OC_EQ:
@@ -1243,41 +1639,13 @@ unit cgcpu;
procedure tcg64favr.a_op64_reg_reg(list : TAsmList;op:TOpCG;size : tcgsize;regsrc,regdst : tregister64);
begin
- internalerror(2011021325);
+ { TODO : a_op64_reg_reg }
end;
procedure tcg64favr.a_op64_const_reg(list : TAsmList;op:TOpCG;size : tcgsize;value : int64;reg : tregister64);
begin
- a_op64_const_reg_reg(list,op,size,value,reg,reg);
- end;
-
-
- procedure tcg64favr.a_op64_const_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;value : int64;regsrc,regdst : tregister64);
- var
- ovloc : tlocation;
- begin
- a_op64_const_reg_reg_checkoverflow(list,op,size,value,regsrc,regdst,false,ovloc);
- end;
-
-
- procedure tcg64favr.a_op64_reg_reg_reg(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64);
- var
- ovloc : tlocation;
- begin
- a_op64_reg_reg_reg_checkoverflow(list,op,size,regsrc1,regsrc2,regdst,false,ovloc);
- end;
-
-
- 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
- internalerror(2011021326);
- end;
-
-
- procedure tcg64favr.a_op64_reg_reg_reg_checkoverflow(list: TAsmList;op:TOpCG;size : tcgsize;regsrc1,regsrc2,regdst : tregister64;setflags : boolean;var ovloc : tlocation);
- begin
- internalerror(2011021327);
+ { TODO : a_op64_const_reg }
end;
diff --git a/compiler/avr/cpubase.pas b/compiler/avr/cpubase.pas
index 4356358107..94ab41a06b 100644
--- a/compiler/avr/cpubase.pas
+++ b/compiler/avr/cpubase.pas
@@ -44,7 +44,7 @@ unit cpubase;
type
TAsmOp=(A_None,
- A_ADD,A_ADC,A_ADIW,A_SUB,A_SUBI,A_SBC,A_SBCI,A_SBIW,A_AND,A_ANDI,
+ A_ADD,A_ADC,A_ADIW,A_SUB,A_SUBI,A_SBC,A_SBCI,A_SBRC,A_SBRS,A_CLC,A_SEC,A_SBIW,A_AND,A_ANDI,
A_OR,A_ORI,A_EOR,A_COM,A_NEG,A_SBR,A_CBR,A_INC,A_DEC,A_TST,A_CLR,
A_SER,A_MUL,A_MULS,A_FMUL,A_FMULS,A_FMULSU,A_RJMP,A_IJMP,
A_EIJMP,A_JMP,A_RCALL,A_ICALL,R_EICALL,A_CALL,A_RET,A_RETI,A_CPSE,
@@ -121,7 +121,7 @@ unit cpubase;
{$i ravrdwa.inc}
);
{ registers which may be destroyed by calls }
- VOLATILE_INTREGISTERS = [RS_R18..RS_R27,RS_R30..RS_R31];
+ VOLATILE_INTREGISTERS = [RS_R0,RS_R1,RS_R8..RS_R27,RS_R30,RS_R31];
VOLATILE_FPUREGISTERS = [];
type
@@ -259,8 +259,8 @@ unit cpubase;
NR_STACK_POINTER_REG = NR_R13;
RS_STACK_POINTER_REG = RS_R13;
{ Frame pointer register }
- RS_FRAME_POINTER_REG = RS_R11;
- NR_FRAME_POINTER_REG = NR_R11;
+ RS_FRAME_POINTER_REG = RS_R28;
+ NR_FRAME_POINTER_REG = NR_R28;
{ Register for addressing absolute data in a position independant way,
such as in PIC code. The exact meaning is ABI specific. For
further information look at GCC source : PIC_OFFSET_TABLE_REGNUM
@@ -306,8 +306,10 @@ unit cpubase;
This value can be deduced from the CALLED_USED_REGISTERS array in the
GCC source.
}
- saved_standard_registers : array[0..6] of tsuperregister =
- (RS_R4,RS_R5,RS_R6,RS_R7,RS_R8,RS_R9,RS_R10);
+ { on avr, gen_entry/gen_exit code saves/restores registers, so
+ we don't need this array }
+ saved_standard_registers : array[0..0] of tsuperregister =
+ (RS_INVALID);
{ Required parameter alignment when calling a routine declared as
stdcall and cdecl. The alignment value should be the one defined
by GCC or the target ABI.
@@ -341,6 +343,11 @@ unit cpubase;
{ returns the next virtual register }
function GetNextReg(const r : TRegister) : TRegister;
+ { returns the last virtual register }
+ function GetLastReg(const r : TRegister) : TRegister;
+
+ function GetOffsetReg(const r : TRegister;ofs : shortint) : TRegister;
+
implementation
uses
@@ -469,4 +476,16 @@ unit cpubase;
result:=TRegister(longint(r)+1);
end;
+
+ function GetLastReg(const r: TRegister): TRegister;
+ begin
+ result:=TRegister(longint(r)-1);
+ end;
+
+
+ function GetOffsetReg(const r: TRegister;ofs : shortint): TRegister;
+ begin
+ result:=TRegister(longint(r)+ofs);
+ end;
+
end.
diff --git a/compiler/avr/cpuinfo.pas b/compiler/avr/cpuinfo.pas
index 0195b88e7b..9496374a63 100644
--- a/compiler/avr/cpuinfo.pas
+++ b/compiler/avr/cpuinfo.pas
@@ -32,8 +32,30 @@ Type
{ possible supported processors for this target }
tcputype =
(cpu_none,
- cpu_avr
+ cpu_avr1,
+ cpu_avr2,
+ cpu_avr25,
+ cpu_avr3,
+ cpu_avr31,
+ cpu_avr35,
+ cpu_avr4,
+ cpu_avr5,
+ cpu_avr51,
+ cpu_avr6
);
+
+ tcpuflags =
+ (AVR_HAVE_JMP_CALL,
+ AVR_HAVE_MOVW,
+ AVR_HAVE_LPMX,
+ AVR_HAVE_MUL,
+ AVR_HAVE_RAMPZ,
+ AVR_HAVE_ELPM,
+ AVR_HAVE_ELPMX,
+ AVR_2_BYTE_PC,
+ AVR_3_BYTE_PC
+ );
+
tfputype =
(fpu_none,
fpu_soft,
@@ -72,7 +94,16 @@ Const
];
cputypestr : array[tcputype] of string[5] = ('',
- 'AVR'
+ 'AVR1',
+ 'AVR2',
+ 'AVR25',
+ 'AVR3',
+ 'AVR31',
+ 'AVR35',
+ 'AVR4',
+ 'AVR5',
+ 'AVR51',
+ 'AVR6'
);
fputypestr : array[tfputype] of string[6] = (
@@ -112,6 +143,20 @@ Const
[cs_opt_regvar,cs_opt_stackframe,cs_opt_tailrecursion];
level3optimizerswitches = genericlevel3optimizerswitches + level2optimizerswitches + [{,cs_opt_loopunroll}];
+ cpu_capabilities : array[tcputype] of set of tcpuflags =
+ ( { cpu_none } [],
+ { cpu_avr1 } [],
+ { cpu_avr2 } [],
+ { cpu_avr25 } [],
+ { cpu_avr3 } [],
+ { cpu_avr31 } [],
+ { cpu_avr35 } [],
+ { cpu_avr4 } [],
+ { cpu_avr5 } [],
+ { cpu_avr51 } [],
+ { cpu_avr6 } []
+ );
+
Implementation
end.
diff --git a/compiler/avr/cpupara.pas b/compiler/avr/cpupara.pas
index 57d84ffb89..d313d24896 100644
--- a/compiler/avr/cpupara.pas
+++ b/compiler/avr/cpupara.pas
@@ -84,17 +84,17 @@ unit cpupara;
begin
size:=OS_INT;
{ the four first parameters are passed into registers }
- if nr<=4 then
+ if nr<=9 then
begin
loc:=LOC_REGISTER;
- register:=newreg(R_INTREGISTER,RS_R0+nr-1,R_SUBWHOLE);
+ register:=newreg(R_INTREGISTER,RS_R25-(nr-1)*2,R_SUBWHOLE);
end
else
begin
{ the other parameters are passed on the stack }
loc:=LOC_REFERENCE;
reference.index:=NR_STACK_POINTER_REG;
- reference.offset:=(nr-5)*4;
+ reference.offset:=(nr-10)*2;
end;
end;
end;
@@ -200,13 +200,14 @@ unit cpupara;
procedure tavrparamanager.init_values(var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword);
begin
- curintreg:=RS_R0;
+ curintreg:=RS_R25;
curfloatreg:=RS_INVALID;
curmmreg:=RS_INVALID;
cur_stack_offset:=0;
end;
+ { TODO : fix tavrparamanager.create_paraloc_info_intern }
function tavrparamanager.create_paraloc_info_intern(p : tabstractprocdef; side: tcallercallee; paras: tparalist;
var curintreg, curfloatreg, curmmreg: tsuperregister; var cur_stack_offset: aword):longint;
@@ -225,7 +226,7 @@ unit cpupara;
begin
{ In case of po_delphi_nested_cc, the parent frame pointer
is always passed on the stack. }
- if (nextintreg<=RS_R3) and
+ if (nextintreg>RS_R8) and
(not(vo_is_parentfp in hp.varoptions) or
not(po_delphi_nested_cc in p.procoptions)) then
begin
@@ -238,7 +239,7 @@ unit cpupara;
paraloc^.loc:=LOC_REFERENCE;
paraloc^.reference.index:=NR_STACK_POINTER_REG;
paraloc^.reference.offset:=stack_offset;
- inc(stack_offset,4);
+ dec(stack_offset,2);
end;
end;
@@ -265,7 +266,7 @@ unit cpupara;
paraloc:=hp.paraloc[side].add_location;
{ hack: the paraloc must be valid, but is not actually used }
paraloc^.loc:=LOC_REGISTER;
- paraloc^.register:=NR_R0;
+ paraloc^.register:=NR_R25;
paraloc^.size:=OS_ADDR;
break;
end;
@@ -333,11 +334,11 @@ unit cpupara;
begin
{ this is not abi compliant
why? (FK) }
- if nextintreg<=RS_R3 then
+ if nextintreg>=RS_R8 then
begin
paraloc^.loc:=LOC_REGISTER;
paraloc^.register:=newreg(R_INTREGISTER,nextintreg,R_SUBWHOLE);
- inc(nextintreg);
+ dec(nextintreg);
end
else
begin
@@ -374,7 +375,7 @@ unit cpupara;
if paraloc^.loc=LOC_REFERENCE then
begin
paraloc^.reference.index:=NR_FRAME_POINTER_REG;
- inc(paraloc^.reference.offset,4);
+ inc(paraloc^.reference.offset,2);
end;
end;
dec(paralen,tcgsize2size[paraloc^.size]);
@@ -408,6 +409,7 @@ unit cpupara;
end;
+ { TODO : fix tavrparamanager.get_funcretloc }
function tavrparamanager.get_funcretloc(p : tabstractprocdef; side: tcallercallee; def: tdef): tcgpara;
var
retcgsize : tcgsize;
diff --git a/compiler/avr/cpupi.pas b/compiler/avr/cpupi.pas
index 18a92a8f4a..e6934f07c3 100644
--- a/compiler/avr/cpupi.pas
+++ b/compiler/avr/cpupi.pas
@@ -33,7 +33,6 @@ unit cpupi;
type
tavrprocinfo = class(tcgprocinfo)
- floatregstart : aint;
// procedure handle_body_start;override;
// procedure after_pass1;override;
procedure set_first_temp_offset;override;
@@ -54,26 +53,14 @@ unit cpupi;
procedure tavrprocinfo.set_first_temp_offset;
begin
- { We allocate enough space to save all registers because we can't determine
- the necessary space because the used registers aren't known before
- secondpass is run. Even worse, patching
- the local offsets after generating the code could cause trouble because
- "shifter" constants could change to non-"shifter" constants. This
- is especially a problem when taking the address of a local. For now,
- this extra memory should hurt less than generating all local contants with offsets
- >256 as non shifter constants }
if tg.direction = -1 then
- tg.setfirsttemp(-12-28)
+ tg.setfirsttemp(0)
else
tg.setfirsttemp(maxpushedparasize);
end;
function tavrprocinfo.calc_stackframe_size:longint;
- var
- firstfloatreg,lastfloatreg,
- r : byte;
- floatsavesize : aword;
begin
maxpushedparasize:=align(maxpushedparasize,max(current_settings.alignment.localalignmin,4));
end;
@@ -82,3 +69,4 @@ unit cpupi;
begin
cprocinfo:=tavrprocinfo;
end.
+
diff --git a/compiler/avr/itcpugas.pas b/compiler/avr/itcpugas.pas
index 1d48e93011..6af73515c7 100644
--- a/compiler/avr/itcpugas.pas
+++ b/compiler/avr/itcpugas.pas
@@ -35,7 +35,7 @@ interface
processor manufacturer.
}
gas_op2str : op2strtable = ('',
- 'add','adc','adiw','sub','subi','sbc','sbci','sbiw','and','andi',
+ 'add','adc','adiw','sub','subi','sbc','sbci','sbrc','sbrs','clc','sec','sbiw','and','andi',
'or','ori','eor','com','neg','sbr','cbr','inc','dec','tst','clr',
'ser','mul','muls','fmul','fmuls','fmulsu','rjmp','ijmp',
'eijmp','jmp','rcall','icall','eicall','call','ret','reti','cpse',
diff --git a/compiler/avr/navradd.pas b/compiler/avr/navradd.pas
index ab94bc1305..aefa78955b 100644
--- a/compiler/avr/navradd.pas
+++ b/compiler/avr/navradd.pas
@@ -120,25 +120,36 @@ interface
procedure tavraddnode.second_cmpsmallset;
+
+ procedure gencmp(tmpreg1,tmpreg2 : tregister);
+ var
+ i : byte;
+ begin
+ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CP,tmpreg1,tmpreg2));
+ for i:=2 to tcgsize2size[left.location.size] do
+ begin
+ tmpreg1:=GetNextReg(tmpreg1);
+ tmpreg2:=GetNextReg(tmpreg2);
+ current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
+ end;
+ end;
+
var
tmpreg : tregister;
begin
- {
pass_left_right;
-
location_reset(location,LOC_FLAGS,OS_NO);
-
force_reg_left_right(false,false);
case nodetype of
equaln:
begin
- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register,right.location.register));
+ gencmp(left.location.register,right.location.register);
location.resflags:=F_EQ;
end;
unequaln:
begin
- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,left.location.register,right.location.register));
+ gencmp(left.location.register,right.location.register);
location.resflags:=F_NE;
end;
lten,
@@ -150,14 +161,14 @@ interface
(nodetype = gten)) then
swapleftright;
tmpreg:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg_reg(A_AND,tmpreg,left.location.register,right.location.register));
- current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CMP,tmpreg,right.location.register));
+ cg.a_op_reg_reg_reg(current_asmdata.CurrAsmList,OP_AND,location.size,
+ left.location.register,right.location.register,tmpreg);
+ gencmp(tmpreg,right.location.register);
location.resflags:=F_EQ;
end;
else
internalerror(2004012401);
end;
- }
end;
@@ -182,6 +193,13 @@ interface
for i:=2 to tcgsize2size[left.location.size] do
begin
+ tmpreg1:=GetNextReg(tmpreg1);
+ tmpreg2:=GetNextReg(tmpreg2);
+ if i=5 then
+ begin
+ tmpreg1:=left.location.registerhi;
+ tmpreg2:=right.location.registerhi;
+ end;
current_asmdata.CurrAsmList.concat(taicpu.op_reg_reg(A_CPC,tmpreg1,tmpreg2));
end;
diff --git a/compiler/avr/navrcnv.pas b/compiler/avr/navrcnv.pas
index fd5cbd218d..4afaf6bc95 100644
--- a/compiler/avr/navrcnv.pas
+++ b/compiler/avr/navrcnv.pas
@@ -44,7 +44,7 @@ interface
{ procedure second_cord_to_pointer;override; }
{ procedure second_proc_to_procvar;override; }
{ procedure second_bool_to_int;override; }
- procedure second_int_to_bool;override;
+ { procedure second_int_to_bool;override; }
{ procedure second_load_smallset;override; }
{ procedure second_ansistring_to_pchar;override; }
{ procedure second_pchar_to_string;override; }
@@ -54,127 +54,6 @@ interface
implementation
- uses
- verbose,globtype,globals,systems,
- symconst,symdef,aasmbase,aasmtai,aasmdata,
- defutil,
- cgbase,cgutils,
- pass_1,pass_2,procinfo,
- ncon,ncal,
- ncgutil,
- cpubase,aasmcpu,
- rgobj,tgobj,cgobj,cgcpu;
-
-
- procedure tarmtypeconvnode.second_int_to_bool;
- var
- hregister : tregister;
- href : treference;
- resflags : tresflags;
- hlabel,oldTrueLabel,oldFalseLabel : tasmlabel;
- newsize : tcgsize;
- begin
- {
- oldTrueLabel:=current_procinfo.CurrTrueLabel;
- oldFalseLabel:=current_procinfo.CurrFalseLabel;
- current_asmdata.getjumplabel(current_procinfo.CurrTrueLabel);
- current_asmdata.getjumplabel(current_procinfo.CurrFalseLabel);
- secondpass(left);
- if codegenerror then
- exit;
-
- { Explicit typecasts from any ordinal type to a boolean type }
- { must not change the ordinal value }
- if (nf_explicit in flags) and
- not(left.location.loc in [LOC_FLAGS,LOC_JUMP]) then
- begin
- location_copy(location,left.location);
- newsize:=def_cgsize(resultdef);
- { change of size? change sign only if location is LOC_(C)REGISTER? Then we have to sign/zero-extend }
- if (tcgsize2size[newsize]<>tcgsize2size[left.location.size]) or
- ((newsize<>left.location.size) and (location.loc in [LOC_REGISTER,LOC_CREGISTER])) then
- location_force_reg(current_asmdata.CurrAsmList,location,newsize,true)
- else
- location.size:=newsize;
- current_procinfo.CurrTrueLabel:=oldTrueLabel;
- current_procinfo.CurrFalseLabel:=oldFalseLabel;
- exit;
- end;
-
- { Load left node into flag F_NE/F_E }
- resflags:=F_NE;
- case left.location.loc of
- LOC_CREFERENCE,
- LOC_REFERENCE :
- begin
- if left.location.size in [OS_64,OS_S64] then
- begin
- hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
- cg.a_load_ref_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.reference,hregister);
- href:=left.location.reference;
- inc(href.offset,4);
- tcgarm(cg).cgsetflags:=true;
- cg.a_op_ref_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,href,hregister);
- tcgarm(cg).cgsetflags:=false;
- end
- else
- begin
- location_force_reg(current_asmdata.CurrAsmList,left.location,left.location.size,true);
- tcgarm(cg).cgsetflags:=true;
- cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
- tcgarm(cg).cgsetflags:=false;
- end;
- end;
- LOC_FLAGS :
- begin
- resflags:=left.location.resflags;
- end;
- LOC_REGISTER,LOC_CREGISTER :
- begin
- if left.location.size in [OS_64,OS_S64] then
- begin
- hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_32);
- cg.a_load_reg_reg(current_asmdata.CurrAsmList,OS_32,OS_32,left.location.register64.reglo,hregister);
- tcgarm(cg).cgsetflags:=true;
- cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_32,left.location.register64.reghi,hregister);
- tcgarm(cg).cgsetflags:=false;
- end
- else
- begin
- tcgarm(cg).cgsetflags:=true;
- cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,left.location.size,left.location.register,left.location.register);
- tcgarm(cg).cgsetflags:=false;
- end;
- end;
- LOC_JUMP :
- begin
- hregister:=cg.getintregister(current_asmdata.CurrAsmList,OS_INT);
- current_asmdata.getjumplabel(hlabel);
- cg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrTrueLabel);
- cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,1,hregister);
- cg.a_jmp_always(current_asmdata.CurrAsmList,hlabel);
- cg.a_label(current_asmdata.CurrAsmList,current_procinfo.CurrFalseLabel);
- cg.a_load_const_reg(current_asmdata.CurrAsmList,OS_INT,0,hregister);
- cg.a_label(current_asmdata.CurrAsmList,hlabel);
- tcgarm(cg).cgsetflags:=true;
- cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_OR,OS_INT,hregister,hregister);
- tcgarm(cg).cgsetflags:=false;
- end;
- else
- internalerror(200311301);
- end;
- { load flags to register }
- location_reset(location,LOC_REGISTER,def_cgsize(resultdef));
- location.register:=cg.getintregister(current_asmdata.CurrAsmList,location.size);
- cg.g_flags2reg(current_asmdata.CurrAsmList,location.size,resflags,location.register);
- if (is_cbool(resultdef)) then
- cg.a_op_reg_reg(current_asmdata.CurrAsmList,OP_NEG,location.size,location.register,location.register);
- current_procinfo.CurrTrueLabel:=oldTrueLabel;
- current_procinfo.CurrFalseLabel:=oldFalseLabel;
- }
- end;
-
-
begin
ctypeconvnode:=tarmtypeconvnode;
end.
diff --git a/compiler/avr/raavrgas.pas b/compiler/avr/raavrgas.pas
index 252f4a7ce9..c5ce6d1fa0 100644
--- a/compiler/avr/raavrgas.pas
+++ b/compiler/avr/raavrgas.pas
@@ -333,13 +333,6 @@ Unit raavrgas;
BuildReference(oper);
end;
- AS_HASH: { Constant expression }
- Begin
- Consume(AS_HASH);
- BuildConstantOperand(oper);
- end;
-
- (*
AS_INTNUM,
AS_MINUS,
AS_PLUS:
@@ -348,16 +341,18 @@ Unit raavrgas;
{ This must absolutely be followed by ( }
oper.InitRef;
oper.opr.ref.offset:=BuildConstExpression(True,False);
- if actasmtoken<>AS_LPAREN then
+
+ { absolute memory addresss? }
+ if actopcode in [A_LDS,A_STS] then
+ BuildReference(oper)
+ else
begin
ofs:=oper.opr.ref.offset;
BuildConstantOperand(oper);
inc(oper.opr.val,ofs);
- end
- else
- BuildReference(oper);
+ end;
end;
- *)
+
AS_ID: { A constant expression, or a Variable ref. }
Begin
{ Local Label ? }
diff --git a/compiler/avr/rgcpu.pas b/compiler/avr/rgcpu.pas
index 34e5f728b0..602ec1c2ff 100644
--- a/compiler/avr/rgcpu.pas
+++ b/compiler/avr/rgcpu.pas
@@ -87,28 +87,80 @@ unit rgcpu;
end;
-
procedure trgcpu.do_spill_read(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
+ var
+ helpins : tai;
+ tmpref : treference;
+ helplist : TAsmList;
+ hreg : tregister;
begin
- inherited do_spill_read(list,pos,spilltemp,tempreg);
+ if abs(spilltemp.offset)>63 then
+ begin
+ helplist:=TAsmList.create;
+
+ helplist.concat(taicpu.op_reg_const(A_LDI,NR_R26,lo(word(spilltemp.offset))));
+ helplist.concat(taicpu.op_reg_const(A_LDI,NR_R27,hi(word(spilltemp.offset))));
+ helplist.concat(taicpu.op_reg_reg(A_ADD,NR_R26,spilltemp.base));
+ helplist.concat(taicpu.op_reg_reg(A_ADC,NR_R27,GetNextReg(spilltemp.base)));
+
+ reference_reset_base(tmpref,NR_R26,0,1);
+ helpins:=spilling_create_load(tmpref,tempreg);
+ helplist.concat(helpins);
+ list.insertlistafter(pos,helplist);
+ helplist.free;
+ end
+ else
+ inherited do_spill_read(list,pos,spilltemp,tempreg);
end;
procedure trgcpu.do_spill_written(list:TAsmList;pos:tai;const spilltemp:treference;tempreg:tregister);
+ var
+ tmpref : treference;
+ helplist : TAsmList;
+ hreg : tregister;
begin
- inherited do_spill_written(list,pos,spilltemp,tempreg);
- end;
+ if abs(spilltemp.offset)>63 then
+ begin
+ helplist:=TAsmList.create;
+
+ helplist.concat(taicpu.op_reg_const(A_LDI,NR_R26,lo(word(spilltemp.offset))));
+ helplist.concat(taicpu.op_reg_const(A_LDI,NR_R27,hi(word(spilltemp.offset))));
+ helplist.concat(taicpu.op_reg_reg(A_ADD,NR_R26,spilltemp.base));
+ helplist.concat(taicpu.op_reg_reg(A_ADC,NR_R27,GetNextReg(spilltemp.base)));
+
+ reference_reset_base(tmpref,NR_R26,0,1);
+ helplist.concat(spilling_create_store(tempreg,tmpref));
+ list.insertlistafter(pos,helplist);
+ helplist.free;
+ end
+ else
+ inherited do_spill_written(list,pos,spilltemp,tempreg);
+ end;
procedure trgintcpu.add_cpu_interferences(p : tai);
var
- r : tregister;
+ r : tsuperregister;
begin
if p.typ=ait_instruction then
begin
case taicpu(p).opcode of
- A_LD:
- ;
+ A_CPI,
+ A_ANDI,
+ A_ORI,
+ A_SUBI,
+ A_SBCI,
+ A_LDI:
+ for r:=RS_R0 to RS_R15 do
+ add_edge(r,GetSupReg(taicpu(p).oper[0]^.reg));
+ A_MULS:
+ begin
+ for r:=RS_R0 to RS_R15 do
+ add_edge(r,GetSupReg(taicpu(p).oper[0]^.reg));
+ for r:=RS_R0 to RS_R15 do
+ add_edge(r,GetSupReg(taicpu(p).oper[1]^.reg));
+ end;
end;
end;
end;