From 26ce3cef00b5e187eeb3c7ef8018278848c61ea6 Mon Sep 17 00:00:00 2001 From: florian Date: Sat, 26 Feb 2011 20:08:23 +0000 Subject: [PATCH] * compilation fixes * completed a_load_ref_reg + implemented procedure entry/exit code generation + implemented a_load_reg_ref git-svn-id: trunk@17009 - --- compiler/avr/agavrgas.pas | 9 - compiler/avr/cgcpu.pas | 580 ++++++++++++++++++++------------------ compiler/avr/cpubase.pas | 17 +- compiler/avr/itcpugas.pas | 4 +- compiler/avr/navrmat.pas | 1 - compiler/avr/raavrgas.pas | 26 +- compiler/cgbase.pas | 4 +- compiler/ppcavr.lpi | 16 +- 8 files changed, 330 insertions(+), 327 deletions(-) diff --git a/compiler/avr/agavrgas.pas b/compiler/avr/agavrgas.pas index 78687187f7..b73e7b4583 100644 --- a/compiler/avr/agavrgas.pas +++ b/compiler/avr/agavrgas.pas @@ -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; diff --git a/compiler/avr/cgcpu.pas b/compiler/avr/cgcpu.pas index 400b98acea..1e4d53ea79 100644 --- a/compiler/avr/cgcpu.pas +++ b/compiler/avr/cgcpu.pas @@ -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 (iNR_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 (iNR_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 (iNR_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 (iNR_NO) and (i0) 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 (i0) 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; diff --git a/compiler/avr/cpubase.pas b/compiler/avr/cpubase.pas index bbd6270f48..4b99bb0832 100644 --- a/compiler/avr/cpubase.pas +++ b/compiler/avr/cpubase.pas @@ -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, diff --git a/compiler/avr/itcpugas.pas b/compiler/avr/itcpugas.pas index aaa571614a..1d48e93011 100644 --- a/compiler/avr/itcpugas.pas +++ b/compiler/avr/itcpugas.pas @@ -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; diff --git a/compiler/avr/navrmat.pas b/compiler/avr/navrmat.pas index 0f7e2d1b41..d4482a62e4 100644 --- a/compiler/avr/navrmat.pas +++ b/compiler/avr/navrmat.pas @@ -80,7 +80,6 @@ implementation helper2, resultreg : tregister; size : Tcgsize; - so : tshifterop; procedure genOrdConstNodeDiv; begin { diff --git a/compiler/avr/raavrgas.pas b/compiler/avr/raavrgas.pas index 65d94ae15e..252f4a7ce9 100644 --- a/compiler/avr/raavrgas.pas +++ b/compiler/avr/raavrgas.pas @@ -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 diff --git a/compiler/cgbase.pas b/compiler/cgbase.pas index 77e69e3c75..c82fe755f3 100644 --- a/compiler/cgbase.pas +++ b/compiler/cgbase.pas @@ -86,8 +86,8 @@ interface {$ENDIF} {$ENDIF} {$IFDEF AVR} - ,lo8 - ,hi + ,addr_lo8 + ,addr_hi8 {$ENDIF} ); diff --git a/compiler/ppcavr.lpi b/compiler/ppcavr.lpi index 03fc46a811..e84350fce4 100644 --- a/compiler/ppcavr.lpi +++ b/compiler/ppcavr.lpi @@ -1,8 +1,8 @@ + - @@ -12,9 +12,11 @@ - </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>