* compilation fixes

* completed a_load_ref_reg
+ implemented procedure entry/exit code generation
+ implemented a_load_reg_ref

git-svn-id: trunk@17009 -
This commit is contained in:
florian 2011-02-26 20:08:23 +00:00
parent 8b245369e1
commit 26ce3cef00
8 changed files with 330 additions and 327 deletions

View File

@ -43,10 +43,6 @@ unit agavrgas;
end;
const
gas_shiftmode2str : array[tshiftmode] of string[3] = (
'','lsl','lsr','asr','ror','rrx');
implementation
uses
@ -88,8 +84,6 @@ unit agavrgas;
if assigned(symbol) then
begin
if (base<>NR_NO) and not(is_pc(base)) then
internalerror(200309011);
s:=symbol.name;
if offset<0 then
s:=s+tostr(offset)
@ -106,9 +100,6 @@ unit agavrgas;
end;
const
shiftmode2str: array[tshiftmode] of string[3] = ('','lsl','lsr','asr','ror','rrx');
function getopstr(const o:toper) : string;
var
hs : string;

View File

@ -48,9 +48,6 @@ unit cgcpu;
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_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;
@ -104,11 +101,12 @@ unit cgcpu;
procedure a_jmp_cond(list : TAsmList;cond : TOpCmp;l: tasmlabel);
procedure fixref(list : TAsmList;var ref : treference);
function normalize_ref(list:TAsmList;op: tasmop;reg:tregister;ref: treference):treference;
function normalize_ref(list:TAsmList;ref: treference):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);
end;
tcg64favr = class(tcg64f32)
@ -351,27 +349,32 @@ unit cgcpu;
procedure tcgavr.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister);
var
tmpreg: tregister;
i : integer;
begin
internalerror(2011021301);
case op of
OP_NEG:
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;
begin
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
{ TODO : Fix me }
internalerror(2011021301);
tmpreg:=GetNextReg(dst);
list.concat(taicpu.op_reg(A_COM,dst));
list.concat(taicpu.op_reg(A_NEG,dst));
list.concat(taicpu.op_const_reg(A_SBC,-1,dst));
end;
end;
OP_NOT:
begin
for i:=1 to cgsize2size[size] do
for i:=1 to tcgsize2size[size] do
begin
if src<>dst then
a_load_reg_reg(list,OS_8,OS_8,src,dst);
list.concat(taicpu.op_reg(A_NOT,S_L,dst));
list.concat(taicpu.op_reg(A_COM,dst));
src:=GetNextReg(src);
dst:=GetNextReg(dst);
end;
@ -408,7 +411,6 @@ unit cgcpu;
procedure tcgavr.a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation);
var
so : tshifterop;
tmpreg,overflowreg : tregister;
asmop : tasmop;
begin
@ -442,7 +444,7 @@ unit cgcpu;
end;
function tcgavr.normalize_ref(list:TAsmList;op: tasmop;reg:tregister;ref: treference):treference;
function tcgavr.normalize_ref(list:TAsmList;ref: treference):treference;
var
tmpreg : tregister;
tmpref : treference;
@ -471,19 +473,19 @@ unit cgcpu;
tmpref.symbol:=ref.symbol;
tmpref.offset:=lo(word(ref.offset));
tmpref.refaddr:=addr_lo8;
list.concat(taicpu.op_reg_reg(A_LDI,tmpreg,tmpref);
list.concat(taicpu.op_reg_ref(A_LDI,tmpreg,tmpref));
tmpref.offset:=hi(word(ref.offset));
tmpref.refaddr:=addr_hi8;
list.concat(taicpu.op_reg_reg(A_LDI,GetNextReg(tmpreg),tmpref);
list.concat(taicpu.op_reg_ref(A_LDI,GetNextReg(tmpreg),tmpref));
if (ref.base<>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.base));
list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.base)));
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.base));
list.concat(taicpu.op_reg_reg(A_ADC,GetNextReg(tmpreg),GetNextReg(ref.base)));
end;
ref.base:=tmpreg;
ref.index:=NR_NO;
@ -491,9 +493,9 @@ unit cgcpu;
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);
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_MOVW,tmpreg,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;
@ -502,29 +504,164 @@ unit cgcpu;
procedure tcgavr.a_load_reg_ref(list : TAsmList; fromsize, tosize: tcgsize; reg : tregister;const ref : treference);
begin
internalerror(2011021305);
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);
var
href : treference;
conv_done: boolean;
tmpreg : tregister;
i : integer;
begin
href:=Ref;
prepareref(list,href);
href:=normalize_ref(list,Ref);
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
if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
href.addressmode:=AM_POSTINCREMENT;
list.concat(taicpu.op_ref_reg(A_ST,href,reg));
for i:=2 to tcgsize2size[tosize] do
begin
if (href.offset<>0) or assigned(href.symbol) then
inc(href.offset);
if (href.base<>NR_NO) 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));
end;
end;
OS_S8:
begin
if (href.base<>NR_NO) and (tcgsize2size[tosize]>1) then
href.addressmode:=AM_POSTINCREMENT;
list.concat(taicpu.op_ref_reg(A_ST,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(A_COM,tmpreg));
for i:=2 to tcgsize2size[tosize] do
begin
if (href.offset<>0) or assigned(href.symbol) then
inc(href.offset);
if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
list.concat(taicpu.op_ref_reg(A_ST,href,tmpreg));
end;
end;
end;
OS_16:
begin
if (href.base<>NR_NO) 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
inc(href.offset)
else if (href.base<>NR_NO) 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));
for i:=3 to tcgsize2size[tosize] do
begin
if (href.offset<>0) or assigned(href.symbol) then
inc(href.offset);
if (href.base<>NR_NO) 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));
end;
end;
OS_S16:
begin
if (href.base<>NR_NO) 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
inc(href.offset)
else if (href.base<>NR_NO) 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));
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(A_COM,tmpreg));
for i:=3 to tcgsize2size[tosize] do
begin
if (href.offset<>0) or assigned(href.symbol) then
inc(href.offset);
if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
list.concat(taicpu.op_ref_reg(A_ST,href,tmpreg));
end;
end;
end;
else
conv_done:=false;
end;
end;
if not conv_done then
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;
list.concat(taicpu.op_ref_reg(A_ST,href,reg));
if (href.offset<>0) or assigned(href.symbol) then
inc(href.offset);
reg:=GetNextReg(reg);
end;
end;
end;
procedure tcgavr.a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;
const Ref : treference;reg : tregister);
var
href : treference;
conv_done: boolean;
tmpreg : tregister;
i : integer;
begin
href:=normalize_ref(list,Ref);
if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
internalerror(2011021307);
@ -546,26 +683,33 @@ unit cgcpu;
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
if tcgsize2size[tosize]>1 then
begin
reg:=GetNextReg(reg);
emit_mov(list,reg2,tmpreg);
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:=reg;
for i:=3 to tcgsize2size[tosize] do
begin
reg:=GetNextReg(reg);
emit_mov(list,reg,tmpreg);
end;
end;
end;
OS_16:
begin
incref(href);
if href.base<>NR_NO then
href.addressmode:=AM_POSTINCREMENT;
list.concat(taicpu.op_reg_ref(A_LD,reg,href));
if (href.offset<>0) or assigned(href.symbol) then
inc(href.offset);
href.addressmode:=AM_UNCHANGED;
reg:=GetNextReg(reg);
list.concat(taicpu.op_reg_ref(A_LD,reg,href));
@ -577,35 +721,47 @@ unit cgcpu;
end;
OS_S16:
begin
{ dest is always at least 32 bit at this point }
emit_mov(list,reg2,reg1);
if href.base<>NR_NO then
href.addressmode:=AM_POSTINCREMENT;
list.concat(taicpu.op_reg_ref(A_LD,reg,href));
if (href.offset<>0) or assigned(href.symbol) then
inc(href.offset);
href.addressmode:=AM_UNCHANGED;
reg1:=GetNextReg(reg1);
reg2:=GetNextReg(reg2);
emit_mov(list,reg2,reg1);
reg:=GetNextReg(reg);
list.concat(taicpu.op_reg_ref(A_LD,reg,href));
tmpreg:=reg;
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;
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(A_COM,reg));
tmpreg:=reg;
for i:=4 to tcgsize2size[tosize] do
begin
reg2:=GetNextReg(reg2);
emit_mov(list,reg2,tmpreg);
reg:=GetNextReg(reg);
emit_mov(list,reg,tmpreg);
end;
end;
else
conv_done:=false;
end;
end;
if not conv_done and (reg1<>reg2) then
if not conv_done then
begin
for i:=1 to tcgsize2size[fromsize] do
begin
emit_mov(list,reg2,reg1);
reg1:=GetNextReg(reg1);
reg2:=GetNextReg(reg2);
if (href.base<>NR_NO) and (i<tcgsize2size[fromsize]) then
href.addressmode:=AM_POSTINCREMENT
else
href.addressmode:=AM_UNCHANGED;
list.concat(taicpu.op_reg_ref(A_LD,reg,href));
if (href.offset<>0) or assigned(href.symbol) then
inc(href.offset);
reg:=GetNextReg(reg);
end;
end;
end;
@ -615,6 +771,7 @@ unit cgcpu;
var
conv_done: boolean;
tmpreg : tregister;
i : integer;
begin
if (tcgsize2size[fromsize]>32) or (tcgsize2size[tosize]>32) or (fromsize=OS_NO) or (tosize=OS_NO) then
internalerror(2011021310);
@ -644,7 +801,7 @@ unit cgcpu;
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;
tmpreg:=reg2;
for i:=3 to tcgsize2size[tosize] do
begin
reg2:=GetNextReg(reg2);
@ -678,7 +835,7 @@ unit cgcpu;
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;
tmpreg:=reg2;
for i:=4 to tcgsize2size[tosize] do
begin
reg2:=GetNextReg(reg2);
@ -738,242 +895,105 @@ unit cgcpu;
internalerror(2011021316);
end;
procedure tcgavr.a_adjust_sp(list : TAsmList; value : longint);
var
i : integer;
begin
case value of
0:
;
-14..-1:
begin
if ((-value) mod 2)<>0 then
list.concat(taicpu.op_reg(A_PUSH,NR_R0));
for i:=1 to (-value) div 2 do
list.concat(taicpu.op_const(A_RCALL,0));
end;
1..7:
begin
for i:=1 to value do
list.concat(taicpu.op_reg(A_POP,NR_R0));
end;
else
begin
list.concat(taicpu.op_reg_const(A_SUBI,NR_R28,lo(word(-value))));
list.concat(taicpu.op_reg_const(A_SBCI,NR_R29,hi(word(-value))));
// get SREG
list.concat(taicpu.op_reg_const(A_IN,NR_R0,NIO_SREG));
// block interrupts
list.concat(taicpu.op_none(A_CLI));
// write high SP
list.concat(taicpu.op_const_reg(A_OUT,NIO_SP_HI,NR_R29));
// release interrupts
list.concat(taicpu.op_const_reg(A_OUT,NIO_SREG,NR_R0));
// write low SP
list.concat(taicpu.op_const_reg(A_OUT,NIO_SP_LO,NR_R28));
end;
end;
end;
procedure tcgavr.g_proc_entry(list : TAsmList;localsize : longint;nostackframe:boolean);
{
var
ref : treference;
shift : byte;
firstfloatreg,lastfloatreg,
r : byte;
regs : tcpuregisterset;
}
reg : tsuperregister;
begin
internalerror(2011021317);
{
LocalSize:=align(LocalSize,4);
if not(nostackframe) then
begin
firstfloatreg:=RS_NO;
{ save floating point registers? }
for r:=RS_F0 to RS_F7 do
if r in rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall) then
begin
if firstfloatreg=RS_NO then
firstfloatreg:=r;
lastfloatreg:=r;
end;
a_reg_alloc(list,NR_STACK_POINTER_REG);
if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
begin
a_reg_alloc(list,NR_FRAME_POINTER_REG);
a_reg_alloc(list,NR_R12);
list.concat(taicpu.op_reg_reg(A_MOV,NR_R12,NR_STACK_POINTER_REG));
end;
{ save int registers }
reference_reset(ref);
ref.index:=NR_STACK_POINTER_REG;
ref.addressmode:=AM_PREINDEXED;
regs:=rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall);
if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
regs:=regs+[RS_R11,RS_R12,RS_R14,RS_R15]
else
if (regs<>[]) or (pi_do_call in current_procinfo.flags) then
include(regs,RS_R14);
if regs<>[] then
list.concat(setoppostfix(taicpu.op_ref_regset(A_STM,ref,regs),PF_FD));
regs:=regs+[RS_R28,RS_R29];
for reg:=RS_R31 downto RS_R0 do
if reg in regs then
list.concat(taicpu.op_reg(A_PUSH,newreg(R_INTREGISTER,reg,R_SUBWHOLE)));
if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
list.concat(taicpu.op_reg_reg_const(A_SUB,NR_FRAME_POINTER_REG,NR_R12,4));
{ allocate necessary stack size
not necessary according to Yury Sidorov
{ don't use a_op_const_reg_reg here because we don't allow register allocations
in the entry/exit code }
if (target_info.system in [system_arm_wince]) and
(localsize>=winstackpagesize) then
begin
if localsize div winstackpagesize<=5 then
begin
if is_shifter_const(localsize,shift) then
list.concat(Taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,localsize))
else
begin
a_load_const_reg(list,OS_ADDR,localsize,NR_R12);
list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
end;
for i:=1 to localsize div winstackpagesize do
begin
if localsize-i*winstackpagesize<4096 then
reference_reset_base(href,NR_STACK_POINTER_REG,-(localsize-i*winstackpagesize))
else
begin
a_load_const_reg(list,OS_ADDR,-(localsize-i*winstackpagesize),NR_R12);
reference_reset_base(href,NR_STACK_POINTER_REG,0);
href.index:=NR_R12;
end;
{ the data stored doesn't matter }
list.concat(Taicpu.op_reg_ref(A_STR,NR_R0,href));
end;
a_reg_dealloc(list,NR_R12);
reference_reset_base(href,NR_STACK_POINTER_REG,0);
{ the data stored doesn't matter }
list.concat(Taicpu.op_reg_ref(A_STR,NR_R0,href));
end
else
begin
current_asmdata.getjumplabel(again);
list.concat(Taicpu.op_reg_const(A_MOV,NR_R12,localsize div winstackpagesize));
a_label(list,again);
{ always shifterop }
list.concat(Taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,winstackpagesize));
reference_reset_base(href,NR_STACK_POINTER_REG,0);
{ the data stored doesn't matter }
list.concat(Taicpu.op_reg_ref(A_STR,NR_R0,href));
list.concat(Taicpu.op_reg_reg_const(A_SUB,NR_R12,NR_R12,1));
a_jmp_cond(list,OC_NE,again);
if is_shifter_const(localsize mod winstackpagesize,shift) then
list.concat(Taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,localsize mod winstackpagesize))
else
begin
a_load_const_reg(list,OS_ADDR,localsize mod winstackpagesize,NR_R12);
list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
end;
a_reg_dealloc(list,NR_R12);
reference_reset_base(href,NR_STACK_POINTER_REG,0);
{ the data stored doesn't matter }
list.concat(Taicpu.op_reg_ref(A_STR,NR_R0,href));
end
end
else
}
if LocalSize<>0 then
if not(is_shifter_const(localsize,shift)) then
begin
if current_procinfo.framepointer=NR_STACK_POINTER_REG then
a_reg_alloc(list,NR_R12);
a_load_const_reg(list,OS_ADDR,LocalSize,NR_R12);
list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
a_reg_dealloc(list,NR_R12);
end
else
begin
a_reg_dealloc(list,NR_R12);
list.concat(taicpu.op_reg_reg_const(A_SUB,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,LocalSize));
end;
if firstfloatreg<>RS_NO then
begin
reference_reset(ref);
if tg.direction*tarmprocinfo(current_procinfo).floatregstart>=1023 then
begin
a_load_const_reg(list,OS_ADDR,-tarmprocinfo(current_procinfo).floatregstart,NR_R12);
list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_R12,current_procinfo.framepointer,NR_R12));
ref.base:=NR_R12;
end
else
begin
ref.base:=current_procinfo.framepointer;
ref.offset:=tarmprocinfo(current_procinfo).floatregstart;
end;
list.concat(taicpu.op_reg_const_ref(A_SFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
lastfloatreg-firstfloatreg+1,ref));
end;
list.concat(taicpu.op_reg_const(A_IN,NR_R28,NIO_SP_LO));
list.concat(taicpu.op_reg_const(A_IN,NR_R29,NIO_SP_HI));
end
else
{ the framepointer cannot be omitted on avr because sp
is not a register but part of the i/o map
}
internalerror(2011021901);
a_adjust_sp(list,-localsize);
end;
}
end;
procedure tcgavr.g_proc_exit(list : TAsmList;parasize : longint;nostackframe:boolean);
{
var
ref : treference;
firstfloatreg,lastfloatreg,
r : byte;
shift : byte;
regs : tcpuregisterset;
LocalSize : longint;
}
regs : tcpuregisterset;
reg : TSuperRegister;
LocalSize : longint;
begin
internalerror(2011021318);
{
if not(nostackframe) then
begin
{ restore floating point register }
firstfloatreg:=RS_NO;
{ save floating point registers? }
for r:=RS_F0 to RS_F7 do
if r in rg[R_FPUREGISTER].used_in_proc-paramanager.get_volatile_registers_fpu(pocall_stdcall) then
begin
if firstfloatreg=RS_NO then
firstfloatreg:=r;
lastfloatreg:=r;
end;
if firstfloatreg<>RS_NO then
begin
reference_reset(ref);
if tg.direction*tarmprocinfo(current_procinfo).floatregstart>=1023 then
begin
a_load_const_reg(list,OS_ADDR,-tarmprocinfo(current_procinfo).floatregstart,NR_R12);
list.concat(taicpu.op_reg_reg_reg(A_SUB,NR_R12,current_procinfo.framepointer,NR_R12));
ref.base:=NR_R12;
end
else
begin
ref.base:=current_procinfo.framepointer;
ref.offset:=tarmprocinfo(current_procinfo).floatregstart;
end;
list.concat(taicpu.op_reg_const_ref(A_LFM,newreg(R_FPUREGISTER,firstfloatreg,R_SUBWHOLE),
lastfloatreg-firstfloatreg+1,ref));
end;
if (current_procinfo.framepointer=NR_STACK_POINTER_REG) then
if current_procinfo.framepointer<>NR_STACK_POINTER_REG then
begin
LocalSize:=current_procinfo.calc_stackframe_size;
if LocalSize<>0 then
if not(is_shifter_const(LocalSize,shift)) then
begin
a_reg_alloc(list,NR_R12);
a_load_const_reg(list,OS_ADDR,LocalSize,NR_R12);
list.concat(taicpu.op_reg_reg_reg(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,NR_R12));
a_reg_dealloc(list,NR_R12);
end
else
begin
list.concat(taicpu.op_reg_reg_const(A_ADD,NR_STACK_POINTER_REG,NR_STACK_POINTER_REG,LocalSize));
end;
a_adjust_sp(list,LocalSize);
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);
if (pi_do_call in current_procinfo.flags) or (regs<>[]) then
begin
exclude(regs,RS_R14);
include(regs,RS_R15);
end;
if regs=[] then
list.concat(taicpu.op_reg_reg(A_MOV,NR_R15,NR_R14))
else
begin
reference_reset(ref);
ref.index:=NR_STACK_POINTER_REG;
ref.addressmode:=AM_PREINDEXED;
list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,regs),PF_FD));
end;
end
else
begin
{ restore int registers and return }
reference_reset(ref);
ref.index:=NR_FRAME_POINTER_REG;
list.concat(setoppostfix(taicpu.op_ref_regset(A_LDM,ref,rg[R_INTREGISTER].used_in_proc-paramanager.get_volatile_registers_int(pocall_stdcall)+[RS_R11,RS_R13,RS_R15]),PF_EA));
end;
end
else
list.concat(taicpu.op_reg_reg(A_MOV,NR_PC,NR_R14));
}
{ the framepointer cannot be omitted on avr because sp
is not a register but part of the i/o map
}
internalerror(2011021902);
end;
list.concat(taicpu.op_none(A_RET));
end;

View File

@ -48,10 +48,10 @@ unit cpubase;
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,
A_CP,A_CPC,A_CPI,A_SBxx,A_BRxx,A_MOV,A_MOVW,A_LDI,A_LDS,A_LD,A_LDD,
A_CP,A_CPC,A_CPI,A_SBIC,A_SBIS,A_BRxx,A_MOV,A_MOVW,A_LDI,A_LDS,A_LD,A_LDD,
A_STS,A_ST,A_STD,A_LPM,A_ELPM,A_SPM,A_IN,A_OUT,A_PUSH,A_POP,
A_LSL,A_LSR,A_ROL,A_ROR,A_ASR,A_SWAP,A_BSET,A_BCLR,A_SBI,A_CBI,
A_BST,A_BLD,A_Sxx,A_Cxx,A_BRAK,A_NOP,A_SLEEP,A_WDR);
A_BST,A_BLD,A_Sxx,A_CLI,A_BRAK,A_NOP,A_SLEEP,A_WDR);
{ This should define the array of instructions as string }
@ -63,7 +63,8 @@ unit cpubase;
{ Last value of opcode enumeration }
lastop = high(tasmop);
jmp_instructions = [A_BRxx,A_SBxx,A_JMP,A_RCALL,A_ICALL,A_EIJMP,A_RJMP,A_CALL,A_RET,A_RETI,A_CPSE,A_IJMP];
jmp_instructions = [A_BRxx,A_SBIC,A_SBIS,A_JMP,A_RCALL,A_ICALL,A_EIJMP,
A_RJMP,A_CALL,A_RET,A_RETI,A_CPSE,A_IJMP];
{*****************************************************************************
Registers
@ -90,6 +91,10 @@ unit cpubase;
NR_ZLO = NR_R30;
NR_ZHI = NR_R31;
NIO_SREG = $3f;
NIO_SP_LO = $3d;
NIO_SP_HI = $3e;
{ Integer Super registers first and last }
first_int_supreg = RS_R0;
first_int_imreg = $10;
@ -424,12 +429,6 @@ unit cpubase;
end;
procedure shifterop_reset(var so : tshifterop);
begin
FillChar(so,sizeof(so),0);
end;
function inverse_cond(const c: TAsmCond): TAsmCond; {$ifdef USEINLINE}inline;{$endif USEINLINE}
const
inverse: array[TAsmCond] of TAsmCond=(C_None,

View File

@ -39,10 +39,10 @@ interface
'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',
'cp','cpc','cpi','sb','br','mov','movw','ldi','lds','ld','ldd',
'cp','cpc','cpi','sbic','sbis','br','mov','movw','ldi','lds','ld','ldd',
'sts','st','std','lpm','elpm','spm','in','out','push','pop',
'lsl','lsr','rol','ror','asr','swap','bset','bclr','sbi','cbi',
'bst','bld','s','c','brak','nop','sleep','wdr');
'bst','bld','s','cli','brak','nop','sleep','wdr');
function gas_regnum_search(const s:string):Tregister;
function gas_regname(r:Tregister):string;

View File

@ -80,7 +80,6 @@ implementation
helper2,
resultreg : tregister;
size : Tcgsize;
so : tshifterop;
procedure genOrdConstNodeDiv;
begin
{

View File

@ -136,16 +136,16 @@ Unit raavrgas;
Procedure tavrattreader.BuildReference(oper : tavroperand);
procedure Consume_RBracket;
procedure Consume_RParen;
begin
if actasmtoken<>AS_RBRACKET then
if actasmtoken<>AS_RPAREN then
Begin
Message(asmr_e_invalid_reference_syntax);
RecoverConsume(true);
end
else
begin
Consume(AS_RBRACKET);
Consume(AS_RPAREN);
if not (actasmtoken in [AS_COMMA,AS_SEPARATOR,AS_END]) then
Begin
Message(asmr_e_invalid_reference_syntax);
@ -172,30 +172,22 @@ Unit raavrgas;
begin
Consume(AS_LBRACKET);
Consume(AS_LPAREN);
if actasmtoken=AS_REGISTER then
begin
oper.opr.ref.base:=actasmregister;
Consume(AS_REGISTER);
{ can either be a register or a right parenthesis }
{ (reg) }
if actasmtoken=AS_RBRACKET then
if actasmtoken=AS_LPAREN then
Begin
Consume_RBracket;
oper.opr.ref.addressmode:=AM_POSTINDEXED;
if actasmtoken=AS_COMMA then
read_index;
Consume_RParen;
exit;
end;
if actasmtoken=AS_COMMA then
if actasmtoken=AS_PLUS then
begin
read_index;
Consume_RBracket;
end;
if actasmtoken=AS_NOT then
begin
consume(AS_NOT);
oper.opr.ref.addressmode:=AM_PREINDEXED;
consume(AS_PLUS);
oper.opr.ref.addressmode:=AM_POSTINCREMENT;
end;
end {end case }
else

View File

@ -86,8 +86,8 @@ interface
{$ENDIF}
{$ENDIF}
{$IFDEF AVR}
,lo8
,hi
,addr_lo8
,addr_hi8
{$ENDIF}
);

View File

@ -1,8 +1,8 @@
<?xml version="1.0"?>
<CONFIG>
<ProjectOptions>
<Version Value="9"/>
<PathDelim Value="\"/>
<Version Value="7"/>
<General>
<Flags>
<MainUnitHasUsesSectionForAllUnits Value="False"/>
@ -12,9 +12,11 @@
</Flags>
<SessionStorage Value="InProjectDir"/>
<MainUnit Value="0"/>
<TargetFileExt Value=".exe"/>
<Title Value="pp"/>
</General>
<BuildModes Count="1">
<Item1 Name="default" Default="True"/>
</BuildModes>
<PublishOptions>
<Version Value="2"/>
<IncludeFileFilter Value="*.(pas|pp|inc|lfm|lpr|lrs|lpi|lpk|sh|xml)"/>
@ -40,14 +42,14 @@
</Units>
</ProjectOptions>
<CompilerOptions>
<Version Value="8"/>
<Version Value="9"/>
<PathDelim Value="\"/>
<Target>
<Filename Value="avr\pp"/>
</Target>
<SearchPaths>
<IncludeFiles Value="avr\"/>
<OtherUnitFiles Value="avr\;systems\"/>
<IncludeFiles Value="avr"/>
<OtherUnitFiles Value="avr;systems"/>
<UnitOutputDirectory Value="avr\lazbuild"/>
</SearchPaths>
<Parsing>
@ -55,6 +57,7 @@
<CStyleOperator Value="False"/>
<AllowLabel Value="False"/>
<CPPInline Value="False"/>
<UseAnsiStrings Value="False"/>
</SyntaxOptions>
</Parsing>
<Linking>
@ -71,8 +74,7 @@
<ConfigFile>
<StopAfterErrCount Value="50"/>
</ConfigFile>
<CustomOptions Value="-davr
"/>
<CustomOptions Value="-davr"/>
<CompilerPath Value="$(CompPath)"/>
</Other>
</CompilerOptions>