From 086ae4b999cda7676d5575d217405ff0cfd10053 Mon Sep 17 00:00:00 2001 From: florian Date: Sun, 10 Mar 2013 10:45:34 +0000 Subject: [PATCH] Merge r22905 and r22906 git-svn-id: trunk@23773 - --- compiler/arm/aasmcpu.pas | 18 +++- compiler/arm/aoptcpu.pas | 189 ++++++++++++++++++++++++++++----- compiler/arm/armatt.inc | 4 +- compiler/arm/armins.dat | 7 +- compiler/arm/armop.inc | 4 +- compiler/arm/cgcpu.pas | 31 +++++- compiler/arm/cpubase.pas | 15 ++- compiler/arm/cpuinfo.pas | 36 ++++--- compiler/systems/t_embed.pas | 2 + rtl/embedded/arm/lm3tempest.pp | 166 ++++++++++++++++------------- 10 files changed, 351 insertions(+), 121 deletions(-) diff --git a/compiler/arm/aasmcpu.pas b/compiler/arm/aasmcpu.pas index 67c45ad14e..da98706f09 100644 --- a/compiler/arm/aasmcpu.pas +++ b/compiler/arm/aasmcpu.pas @@ -180,6 +180,7 @@ uses constructor op_reg_reg_reg(op : tasmop;_op1,_op2,_op3 : tregister); constructor op_reg_reg_const(op : tasmop;_op1,_op2 : tregister; _op3: aint); + constructor op_reg_const_const(op : tasmop;_op1 : tregister; _op2,_op3: aint); constructor op_reg_reg_sym_ofs(op : tasmop;_op1,_op2 : tregister; _op3: tasmsymbol;_op3ofs: longint); constructor op_reg_reg_ref(op : tasmop;_op1,_op2 : tregister; const _op3: treference); constructor op_reg_reg_shifterop(op : tasmop;_op1,_op2 : tregister;_op3 : tshifterop); @@ -473,6 +474,16 @@ implementation end; + constructor taicpu.op_reg_const_const(op : tasmop;_op1 : tregister; _op2,_op3: aint); + begin + inherited create(op); + ops:=3; + loadreg(0,_op1); + loadconst(1,aint(_op2)); + loadconst(2,aint(_op3)); + end; + + constructor taicpu.op_reg_const_ref(op : tasmop;_op1 : tregister;_op2 : aint;_op3 : treference); begin inherited create(op); @@ -735,11 +746,16 @@ implementation { check for pre/post indexed } result := operand_read; //Thumb2 - A_LSL, A_LSR, A_ROR, A_ASR, A_SDIV, A_UDIV, A_MOVW, A_MOVT, A_MLS: + A_LSL, A_LSR, A_ROR, A_ASR, A_SDIV, A_UDIV, A_MOVW, A_MOVT, A_MLS, A_BFI: if opnr in [0] then result:=operand_write else result:=operand_read; + A_BFC: + if opnr in [0] then + result:=operand_readwrite + else + result:=operand_read; A_LDREX: if opnr in [0] then result:=operand_write diff --git a/compiler/arm/aoptcpu.pas b/compiler/arm/aoptcpu.pas index 028c70bf05..3f1266fcf0 100644 --- a/compiler/arm/aoptcpu.pas +++ b/compiler/arm/aoptcpu.pas @@ -1035,6 +1035,12 @@ Implementation A_AND, A_BIC, A_EOR, A_ORR, A_TEQ, A_TST, A_CMP, A_CMN], [taicpu(p).condition], [PF_None]) and + (not ((current_settings.cputype in cpu_thumb2) and + (taicpu(hp1).opcode in [A_SBC]) and + (((taicpu(hp1).ops=3) and + MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[1]^.reg)) or + ((taicpu(hp1).ops=2) and + MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[0]^.reg))))) and (assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) or regLoadedWithNewValue(taicpu(p).oper[0]^.reg, hp1)) and (taicpu(hp1).ops >= 2) and @@ -1228,13 +1234,13 @@ Implementation end { change - and reg2,reg1,255 + and reg2,reg1,$xxxxxxFF strb reg2,[...] dealloc reg2 to strb reg1,[...] } - else if (taicpu(p).oper[2]^.val = 255) and + else if ((taicpu(p).oper[2]^.val and $FF) = $FF) and MatchInstruction(p, A_AND, [C_None], [PF_None]) and GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and MatchInstruction(hp1, A_STR, [C_None], [PF_B]) and @@ -1249,6 +1255,29 @@ Implementation asml.remove(p); p.free; p:=hp1; + result:=true; + end + { + change + and reg2,reg1,255 + uxtb/uxth reg3,reg2 + dealloc reg2 + to + and reg3,reg1,x + } + else if (taicpu(p).oper[2]^.val = $FF) and + MatchInstruction(p, A_AND, [C_None], [PF_None]) and + GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and + MatchInstruction(hp1, [A_UXTB,A_UXTH], [C_None], [PF_None]) and + assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) and + MatchOperand(taicpu(hp1).oper[1]^, taicpu(p).oper[0]^.reg) and + { reg1 might not be modified inbetween } + not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then + begin + DebugMsg('Peephole AndUxt2And done', p); + taicpu(p).loadReg(0,taicpu(hp1).oper[0]^.reg); + asml.remove(hp1); + result:=true; end { from @@ -1455,9 +1484,11 @@ Implementation begin DebugMsg('Peephole UxtbStrb2Strb done', p); taicpu(hp1).loadReg(0,taicpu(p).oper[1]^.reg); + GetNextInstruction(p,hp2); asml.remove(p); p.free; - p:=hp1; + p:=hp2; + result:=true; end { change @@ -1471,16 +1502,18 @@ Implementation GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and MatchInstruction(hp1, A_UXTH, [C_None], [PF_None]) and (assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) or - (taicpu(p).oper[0]^.reg = taicpu(hp1).oper[0]^.reg)) and + (taicpu(p).oper[0]^.reg = taicpu(hp1).oper[1]^.reg)) and { reg1 might not be modified inbetween } not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then begin DebugMsg('Peephole UxtbUxth2Uxtb done', p); taicpu(hp1).opcode:=A_UXTB; taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); + GetNextInstruction(p,hp2); asml.remove(p); p.free; - p:=hp1; + p:=hp2; + result:=true; end { change @@ -1494,43 +1527,64 @@ Implementation GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and MatchInstruction(hp1, A_UXTB, [C_None], [PF_None]) and (assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) or - (taicpu(p).oper[0]^.reg = taicpu(hp1).oper[0]^.reg)) and + (taicpu(p).oper[0]^.reg = taicpu(hp1).oper[1]^.reg)) and { reg1 might not be modified inbetween } not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then begin DebugMsg('Peephole UxtbUxtb2Uxtb done', p); taicpu(hp1).opcode:=A_UXTB; taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); + GetNextInstruction(p,hp2); asml.remove(p); p.free; - p:=hp1; + p:=hp2; + result:=true; end { change - uxth reg2,reg1 - uxth reg3,reg2 + uxtb reg2,reg1 + and reg3,reg2,#0x*FF dealloc reg2 to - uxth reg3,reg1 + uxtb reg3,reg1 } - else if MatchInstruction(p, A_UXTH, [C_None], [PF_None]) and + else if MatchInstruction(p, A_UXTB, [C_None], [PF_None]) and GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and - MatchInstruction(hp1, A_UXTH, [C_None], [PF_None]) and + MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and + (taicpu(hp1).ops=3) and + (taicpu(hp1).oper[2]^.typ=top_const) and + ((taicpu(hp1).oper[2]^.val and $FF)=$FF) and (assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) or - (taicpu(p).oper[0]^.reg = taicpu(hp1).oper[0]^.reg)) and + (taicpu(p).oper[0]^.reg = taicpu(hp1).oper[1]^.reg)) and { reg1 might not be modified inbetween } not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then begin - DebugMsg('Peephole UxthUxth2Uxth done', p); - taicpu(hp1).opcode:=A_UXTH; + DebugMsg('Peephole UxtbAndImm2Uxtb done', p); + taicpu(hp1).opcode:=A_UXTB; + taicpu(hp1).ops:=2; taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); + GetNextInstruction(p,hp2); asml.remove(p); p.free; - p:=hp1; + p:=hp2; + result:=true; + end + else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then + begin + //if (taicpu(p).ops=3) then + RemoveSuperfluousMove(p, hp1, 'UxtbMov2Data'); end; end; A_UXTH: begin + { + change + uxth reg2,reg1 + strh reg2,[...] + dealloc reg2 + to + strh reg1,[...] + } if MatchInstruction(p, taicpu(p).opcode, [C_None], [PF_None]) and GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and MatchInstruction(hp1, A_STR, [C_None], [PF_H]) and @@ -1545,6 +1599,64 @@ Implementation asml.remove(p); p.free; p:=hp1; + result:=true; + end + { + change + uxth reg2,reg1 + uxth reg3,reg2 + dealloc reg2 + to + uxth reg3,reg1 + } + else if MatchInstruction(p, A_UXTH, [C_None], [PF_None]) and + GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and + MatchInstruction(hp1, A_UXTH, [C_None], [PF_None]) and + (assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) or + (taicpu(p).oper[0]^.reg = taicpu(hp1).oper[1]^.reg)) and + { reg1 might not be modified inbetween } + not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then + begin + DebugMsg('Peephole UxthUxth2Uxth done', p); + taicpu(hp1).opcode:=A_UXTH; + taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); + asml.remove(p); + p.free; + p:=hp1; + result:=true; + end + { + change + uxth reg2,reg1 + and reg3,reg2,#65535 + dealloc reg2 + to + uxth reg3,reg1 + } + else if MatchInstruction(p, A_UXTH, [C_None], [PF_None]) and + GetNextInstructionUsingReg(p,hp1,taicpu(p).oper[0]^.reg) and + MatchInstruction(hp1, A_AND, [C_None], [PF_None]) and + (taicpu(hp1).ops=3) and + (taicpu(hp1).oper[2]^.typ=top_const) and + ((taicpu(hp1).oper[2]^.val and $FFFF)=$FFFF) and + (assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) or + (taicpu(p).oper[0]^.reg = taicpu(hp1).oper[1]^.reg)) and + { reg1 might not be modified inbetween } + not(RegModifiedBetween(taicpu(p).oper[1]^.reg,p,hp1)) then + begin + DebugMsg('Peephole UxthAndImm2Uxth done', p); + taicpu(hp1).opcode:=A_UXTH; + taicpu(hp1).ops:=2; + taicpu(hp1).loadReg(1,taicpu(p).oper[1]^.reg); + asml.remove(p); + p.free; + p:=hp1; + result:=true; + end + else if GetNextInstructionUsingReg(p, hp1, taicpu(p).oper[0]^.reg) then + begin + //if (taicpu(p).ops=3) then + RemoveSuperfluousMove(p, hp1, 'UxthMov2Data'); end; end; A_CMP: @@ -2091,12 +2203,16 @@ Implementation hp : taicpu; hp1,hp2 : tai; begin - if (p.typ=ait_instruction) and + result:=false; + if inherited PeepHoleOptPass1Cpu(p) then + result:=true + else if (p.typ=ait_instruction) and MatchInstruction(p, A_STM, [C_None], [PF_FD,PF_DB]) and (taicpu(p).oper[0]^.ref^.addressmode=AM_PREINDEXED) and (taicpu(p).oper[0]^.ref^.index=NR_STACK_POINTER_REG) and ((taicpu(p).oper[1]^.regset^*[8..13,15])=[]) then begin + DebugMsg('Peephole Stm2Push done', p); hp := taicpu.op_regset(A_PUSH, R_INTREGISTER, R_SUBWHOLE, taicpu(p).oper[1]^.regset^); AsmL.InsertAfter(hp, p); asml.Remove(p); @@ -2110,6 +2226,7 @@ Implementation (taicpu(p).oper[1]^.ref^.offset=-4) and (getsupreg(taicpu(p).oper[0]^.reg) in [0..7,14]) then begin + DebugMsg('Peephole Str2Push done', p); hp := taicpu.op_regset(A_PUSH, R_INTREGISTER, R_SUBWHOLE, [getsupreg(taicpu(p).oper[0]^.reg)]); asml.InsertAfter(hp, p); asml.Remove(p); @@ -2123,6 +2240,7 @@ Implementation (taicpu(p).oper[0]^.ref^.index=NR_STACK_POINTER_REG) and ((taicpu(p).oper[1]^.regset^*[8..14])=[]) then begin + DebugMsg('Peephole Ldm2Pop done', p); hp := taicpu.op_regset(A_POP, R_INTREGISTER, R_SUBWHOLE, taicpu(p).oper[1]^.regset^); asml.InsertBefore(hp, p); asml.Remove(p); @@ -2137,6 +2255,7 @@ Implementation (taicpu(p).oper[1]^.ref^.offset=4) and (getsupreg(taicpu(p).oper[0]^.reg) in [0..7,15]) then begin + DebugMsg('Peephole Ldr2Pop done', p); hp := taicpu.op_regset(A_POP, R_INTREGISTER, R_SUBWHOLE, [getsupreg(taicpu(p).oper[0]^.reg)]); asml.InsertBefore(hp, p); asml.Remove(p); @@ -2151,6 +2270,7 @@ Implementation (taicpu(p).oper[1]^.val < 256) and (not RegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs)) then begin + DebugMsg('Peephole Mov2Movs done', p); asml.InsertBefore(tai_regalloc.alloc(NR_DEFAULTFLAGS,p), p); asml.InsertAfter(tai_regalloc.dealloc(NR_DEFAULTFLAGS,p), p); IncludeRegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs); @@ -2162,6 +2282,7 @@ Implementation (taicpu(p).oper[1]^.typ=top_reg) and (not RegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs)) then begin + DebugMsg('Peephole Mvn2Mvns done', p); asml.InsertBefore(tai_regalloc.alloc(NR_DEFAULTFLAGS,p), p); asml.InsertAfter(tai_regalloc.dealloc(NR_DEFAULTFLAGS,p), p); IncludeRegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs); @@ -2178,6 +2299,7 @@ Implementation (taicpu(p).oper[2]^.val < 256) and (not RegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs)) then begin + DebugMsg('Peephole AddSub2*s done', p); asml.InsertBefore(tai_regalloc.alloc(NR_DEFAULTFLAGS,p), p); asml.InsertAfter(tai_regalloc.dealloc(NR_DEFAULTFLAGS,p), p); IncludeRegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs); @@ -2192,6 +2314,7 @@ Implementation MatchOperand(taicpu(p).oper[0]^, taicpu(p).oper[1]^) and (taicpu(p).oper[2]^.typ=top_reg) then begin + DebugMsg('Peephole AddRRR2AddRR done', p); taicpu(p).ops := 2; taicpu(p).loadreg(1,taicpu(p).oper[2]^.reg); result:=true; @@ -2211,6 +2334,19 @@ Implementation taicpu(p).oppostfix:=PF_S; result:=true; end + else if (p.typ=ait_instruction) and + MatchInstruction(p, [A_AND,A_ORR,A_EOR,A_BIC,A_LSL,A_LSR,A_ASR,A_ROR], [C_None], [PF_S]) and + (taicpu(p).ops = 3) and + MatchOperand(taicpu(p).oper[0]^, taicpu(p).oper[1]^) and + (taicpu(p).oper[2]^.typ in [top_reg,top_const]) then + begin + taicpu(p).ops := 2; + if taicpu(p).oper[2]^.typ=top_reg then + taicpu(p).loadreg(1,taicpu(p).oper[2]^.reg) + else + taicpu(p).loadconst(1,taicpu(p).oper[2]^.val); + result:=true; + end else if (p.typ=ait_instruction) and MatchInstruction(p, [A_AND,A_ORR,A_EOR], [C_None], [PF_None,PF_S]) and (taicpu(p).ops = 3) and @@ -2229,19 +2365,15 @@ Implementation (taicpu(p).ops=3) and (taicpu(p).oper[2]^.typ=top_shifterop) and (taicpu(p).oper[2]^.shifterop^.shiftmode in [SM_LSL,SM_LSR,SM_ASR,SM_ROR]) and - MatchOperand(taicpu(p).oper[0]^, taicpu(p).oper[1]^) and + //MatchOperand(taicpu(p).oper[0]^, taicpu(p).oper[1]^) and (not RegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs)) then begin + DebugMsg('Peephole Mov2Shift done', p); asml.InsertBefore(tai_regalloc.alloc(NR_DEFAULTFLAGS,p), p); asml.InsertAfter(tai_regalloc.dealloc(NR_DEFAULTFLAGS,p), p); IncludeRegInUsedRegs(NR_DEFAULTFLAGS,UsedRegs); taicpu(p).oppostfix:=PF_S; - taicpu(p).ops := 2; - - if taicpu(p).oper[2]^.shifterop^.rs<>NR_NO then - taicpu(p).loadreg(1, taicpu(p).oper[2]^.shifterop^.rs) - else - taicpu(p).loadconst(1, taicpu(p).oper[2]^.shifterop^.shiftimm); + //taicpu(p).ops := 2; case taicpu(p).oper[2]^.shifterop^.shiftmode of SM_LSL: taicpu(p).opcode:=A_LSL; @@ -2249,6 +2381,11 @@ Implementation SM_ASR: taicpu(p).opcode:=A_ASR; SM_ROR: taicpu(p).opcode:=A_ROR; end; + + if taicpu(p).oper[2]^.shifterop^.rs<>NR_NO then + taicpu(p).loadreg(2, taicpu(p).oper[2]^.shifterop^.rs) + else + taicpu(p).loadconst(2, taicpu(p).oper[2]^.shifterop^.shiftimm); result:=true; end else if (p.typ=ait_instruction) and @@ -2258,6 +2395,7 @@ Implementation ((taicpu(p).oper[1]^.val=255) or (taicpu(p).oper[1]^.val=65535)) then begin + DebugMsg('Peephole AndR2Uxt done', p); if taicpu(p).oper[1]^.val=255 then taicpu(p).opcode:=A_UXTB else @@ -2274,6 +2412,7 @@ Implementation ((taicpu(p).oper[2]^.val=255) or (taicpu(p).oper[2]^.val=65535)) then begin + DebugMsg('Peephole AndRR2Uxt done', p); if taicpu(p).oper[2]^.val=255 then taicpu(p).opcode:=A_UXTB else @@ -2383,8 +2522,6 @@ Implementation result := true; end} - else - Result := inherited PeepHoleOptPass1Cpu(p); end; procedure TCpuThumb2AsmOptimizer.PeepHoleOptPass2; diff --git a/compiler/arm/armatt.inc b/compiler/arm/armatt.inc index 43689c752b..d146ffc5bf 100644 --- a/compiler/arm/armatt.inc +++ b/compiler/arm/armatt.inc @@ -241,6 +241,8 @@ 'sxtah', 'sxtb', 'sxtb16', +'uxtb', +'uxth', 'sxth', 'uadd16', 'uadd8', @@ -269,9 +271,7 @@ 'uxtab', 'uxtab16', 'uxtah', -'uxtb', 'uxtb16', -'uxth', 'wfe', 'wfi', 'yield', diff --git a/compiler/arm/armins.dat b/compiler/arm/armins.dat index 79bf5fc798..d193fb7d47 100644 --- a/compiler/arm/armins.dat +++ b/compiler/arm/armins.dat @@ -662,6 +662,10 @@ reg32,reg32,reg32,reg32 \x16\x00\x80\x90 ARM7 [SXTAHcc] [SXTBcc] [SXTB16cc] + +[UXTBcc] +[UXTHcc] + [SXTHcc] [UADD16cc] @@ -699,10 +703,7 @@ reg32,reg32,reg32,reg32 \x16\x00\x80\x90 ARM7 [UXTABcc] [UXTAB16cc] [UXTAHcc] - -[UXTBcc] [UXTB16cc] -[UXTHcc] [WFEcc] [WFIcc] diff --git a/compiler/arm/armop.inc b/compiler/arm/armop.inc index 32d962f451..a95685105b 100644 --- a/compiler/arm/armop.inc +++ b/compiler/arm/armop.inc @@ -241,6 +241,8 @@ A_SXTAB16, A_SXTAH, A_SXTB, A_SXTB16, +A_UXTB, +A_UXTH, A_SXTH, A_UADD16, A_UADD8, @@ -269,9 +271,7 @@ A_USUB8, A_UXTAB, A_UXTAB16, A_UXTAH, -A_UXTB, A_UXTB16, -A_UXTH, A_WFE, A_WFI, A_YIELD, diff --git a/compiler/arm/cgcpu.pas b/compiler/arm/cgcpu.pas index bbe71a7a89..d3a95c4250 100644 --- a/compiler/arm/cgcpu.pas +++ b/compiler/arm/cgcpu.pas @@ -186,6 +186,7 @@ unit cgcpu; procedure a_load_const_reg(list : TAsmList; size: tcgsize; a : tcgint;reg : tregister);override; procedure a_load_ref_reg(list : TAsmList; fromsize, tosize : tcgsize;const Ref : treference;reg : tregister);override; + procedure a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); override; procedure a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation);override; procedure a_op_reg_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; src1, src2, dst: tregister;setflags : boolean;var ovloc : tlocation);override; @@ -1540,12 +1541,12 @@ unit cgcpu; list.Concat(taicpu.op_reg_reg_const(A_RSB,dst,dst,31)); list.Concat(taicpu.op_reg_reg_const(A_AND,dst,dst,255)); end - { it is decided during the compilation of the system unit if this code is used or not + { it is decided during the compilation of the system unit if this code is used or not so no additional check for rbit is needed } else begin list.Concat(taicpu.op_reg_reg(A_RBIT,dst,src)); - list.Concat(taicpu.op_reg_reg(A_CLZ,dst,dst)); + list.Concat(taicpu.op_reg_reg(A_CLZ,dst,dst)); a_reg_alloc(list,NR_DEFAULTFLAGS); list.Concat(taicpu.op_reg_const(A_CMP,dst,32)); if current_settings.cputype in cpu_thumb2 then @@ -4021,9 +4022,26 @@ unit cgcpu; end; + procedure tthumb2cgarm.a_op_reg_reg(list : TAsmList; Op: TOpCG; size: TCGSize; src, dst: TRegister); + begin + if op = OP_NOT then + begin + list.concat(taicpu.op_reg_reg(A_MVN,dst,src)); + case size of + OS_8: list.concat(taicpu.op_reg_reg(A_UXTB,dst,dst)); + OS_S8: list.concat(taicpu.op_reg_reg(A_SXTB,dst,dst)); + OS_16: list.concat(taicpu.op_reg_reg(A_UXTH,dst,dst)); + OS_S16: list.concat(taicpu.op_reg_reg(A_SXTH,dst,dst)); + end; + end + else + inherited a_op_reg_reg(list, op, size, src, dst); + end; + + procedure tthumb2cgarm.a_op_const_reg_reg_checkoverflow(list: TAsmList; op: TOpCg; size: tcgsize; a: tcgint; src, dst: tregister;setflags : boolean;var ovloc : tlocation); var - shift : byte; + shift, width : byte; tmpreg : tregister; so : tshifterop; l1 : longint; @@ -4198,8 +4216,15 @@ unit cgcpu; list.concat(taicpu.op_reg_reg_const(A_BIC,dst,src,not(dword(a))))} else if (op = OP_AND) and is_thumb32_imm(a) then list.concat(taicpu.op_reg_reg_const(A_MOV,dst,src,dword(a))) + else if (op = OP_AND) and (a = $FFFF) then + list.concat(taicpu.op_reg_reg(A_UXTH,dst,src)) else if (op = OP_AND) and is_thumb32_imm(not(dword(a))) then list.concat(taicpu.op_reg_reg_const(A_BIC,dst,src,not(dword(a)))) + else if (op = OP_AND) and is_continuous_mask(not(a), shift, width) then + begin + a_load_reg_reg(list,size,size,src,dst); + list.concat(taicpu.op_reg_const_const(A_BFC,dst,shift,width)) + end else begin tmpreg:=getintregister(list,size); diff --git a/compiler/arm/cpubase.pas b/compiler/arm/cpubase.pas index f14f47e023..66fde1929c 100644 --- a/compiler/arm/cpubase.pas +++ b/compiler/arm/cpubase.pas @@ -46,7 +46,7 @@ unit cpubase; TAsmOp= {$i armop.inc} {This is a bit of a hack, because there are more than 256 ARM Assembly Ops But FPC currently can't handle more than 256 elements in a set.} - TCommonAsmOps = Set of A_None .. A_UQASX; + TCommonAsmOps = Set of A_None .. A_UADD16; { This should define the array of instructions as string } op2strtable=array[tasmop] of string[11]; @@ -368,6 +368,7 @@ unit cpubase; doesn't handle ROR_C detection } function is_thumb32_imm(d : aint) : boolean; function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword):boolean; + function is_continuous_mask(d : aint;var lsb, width: byte) : boolean; function dwarf_reg(r:tregister):shortint; function IsIT(op: TAsmOp) : boolean; @@ -595,6 +596,18 @@ unit cpubase; exit; end; end; + + function is_continuous_mask(d : aint;var lsb, width: byte) : boolean; + var + msb : byte; + begin + lsb:=BsfDword(d); + msb:=BsrDword(d); + + width:=msb-lsb+1; + + result:=(lsb<>255) and (msb<>255) and ((((1 shl (msb-lsb+1))-1) shl lsb) = d); + end; function split_into_shifter_const(value : aint;var imm1: dword; var imm2: dword) : boolean; diff --git a/compiler/arm/cpuinfo.pas b/compiler/arm/cpuinfo.pas index b7bbe6ec5c..f615ba6f69 100644 --- a/compiler/arm/cpuinfo.pas +++ b/compiler/arm/cpuinfo.pas @@ -197,7 +197,9 @@ Type ct_lm3s9b92, ct_lm3s9b95, ct_lm3s9b96, - + + ct_lm3s5d51, + { TI Stellaris } ct_lm4f120h5, @@ -943,7 +945,7 @@ Const sramsize:$00010000 ), - { TI - Tempest parts - 256 K Flash, 64 K SRAM } + { TI - Tempest parts - up to 512 K Flash, 96 K SRAM } // ct_lm3s5951, ( controllertypestr:'LM3S5951'; @@ -969,7 +971,7 @@ Const flashbase:$00000000; flashsize:$00040000; srambase:$20000000; - sramsize:$00010000 + sramsize:$00018000 ), // ct_lm3s2b93, ( @@ -978,7 +980,7 @@ Const flashbase:$00000000; flashsize:$00040000; srambase:$20000000; - sramsize:$00010000 + sramsize:$00018000 ), // ct_lm3s5b91, ( @@ -987,7 +989,7 @@ Const flashbase:$00000000; flashsize:$00040000; srambase:$20000000; - sramsize:$00010000 + sramsize:$00018000 ), // ct_lm3s9b81, ( @@ -996,7 +998,7 @@ Const flashbase:$00000000; flashsize:$00040000; srambase:$20000000; - sramsize:$00010000 + sramsize:$00018000 ), // ct_lm3s9b90, ( @@ -1005,7 +1007,7 @@ Const flashbase:$00000000; flashsize:$00040000; srambase:$20000000; - sramsize:$00010000 + sramsize:$00018000 ), // ct_lm3s9b92, ( @@ -1014,7 +1016,7 @@ Const flashbase:$00000000; flashsize:$00040000; srambase:$20000000; - sramsize:$00010000 + sramsize:$00018000 ), // ct_lm3s9b95, ( @@ -1023,7 +1025,7 @@ Const flashbase:$00000000; flashsize:$00040000; srambase:$20000000; - sramsize:$00010000 + sramsize:$00018000 ), // ct_lm3s9b96, ( @@ -1032,7 +1034,17 @@ Const flashbase:$00000000; flashsize:$00040000; srambase:$20000000; - sramsize:$00010000 + sramsize:$00018000 + ), + + // ct_lm3s5d51, + ( + controllertypestr:'LM3S5D51'; + controllerunitstr:'LM3TEMPEST'; + flashbase:$00000000; + flashsize:$00080000; + srambase:$20000000; + sramsize:$00018000 ), // ct_lm4f120h5, @@ -1060,9 +1072,9 @@ Const controllertypestr:'THUMB2_BARE'; controllerunitstr:'THUMB2_BARE'; flashbase:$00000000; - flashsize:$00100000; + flashsize:$00002000; srambase:$20000000; - sramsize:$00100000 + sramsize:$00000400 ) ); diff --git a/compiler/systems/t_embed.pas b/compiler/systems/t_embed.pas index 4106a2214b..6668027bc1 100644 --- a/compiler/systems/t_embed.pas +++ b/compiler/systems/t_embed.pas @@ -339,6 +339,8 @@ begin ct_lm3s9b95, ct_lm3s9b96, + ct_lm3s5d51, + { TI - Stellaris something } ct_lm4f120h5, diff --git a/rtl/embedded/arm/lm3tempest.pp b/rtl/embedded/arm/lm3tempest.pp index f01fc6b6e9..3fdf7dc7f5 100644 --- a/rtl/embedded/arm/lm3tempest.pp +++ b/rtl/embedded/arm/lm3tempest.pp @@ -6,7 +6,7 @@ based on stm32f103 created by Jeppe Johansen 2009 - jepjoh2@kom.aau.dk } {$goto on} unit lm3tempest; - +{$define highspeedports} interface type @@ -17,8 +17,20 @@ unit lm3tempest; PeripheralBase = $40000000; PPBbase = $E0000fff; APBbase = PeripheralBase; - AHBbase = PeripheralBase+$54000; - portAoffset=APBbase+$4000; + +{$ifdef highspeedports} + portAoffset=APBbase+$58000; + portBoffset=APBbase+$59000; + portCoffset=APBbase+$5A000; + portDoffset=APBbase+$5B000; + portEoffset=APBbase+$5C000; + portFoffset=APBbase+$5D000; + portGoffset=APBbase+$5E000; + portHoffset=APBbase+$5F000; + portJoffset=APBbase+$60000; + +{$else} + portAoffset=APBbase+$4000; portBoffset=APBbase+$5000; portCoffset=APBbase+$6000; portDoffset=APBbase+$7000; @@ -27,9 +39,9 @@ unit lm3tempest; portGoffset=APBbase+$26000; portHoffset=APBbase+$27000; portJoffset=APBbase+$3d000; +{$endif} sysconoffset=APBbase+$fe000; - - + type TgpioPort=record data:array[0..255] of dword;dir,_is,ibe,iev,im,ris,mis,icr, @@ -57,9 +69,9 @@ unit lm3tempest; PortJ :Tgpioport absolute portJoffset; syscon :Tsyscon absolute sysconoffset; - rcgc0 :dword absolute (sysconoffset+$100); - rcgc1 :dword absolute (sysconoffset+$104); - rcgc2 :dword absolute (sysconoffset+$108); + // rcgc0 :dword absolute (sysconoffset+$100); + // rcgc1 :dword absolute (sysconoffset+$104); + // rcgc2 :dword absolute (sysconoffset+$108); implementation @@ -85,6 +97,7 @@ procedure PWM_Fault_Interrupt; external name 'PWM_Fault_Interrupt'; procedure PWM_Generator_0_Interrupt; external name 'PWM_Generator_0_Interrupt'; procedure PWM_Generator_1_Interrupt; external name 'PWM_Generator_1_Interrupt'; procedure PWM_Generator_2_Interrupt; external name 'PWM_Generator_2_Interrupt'; +procedure PWM_Generator_3_Interrupt; external name 'PWM_Generator_3_Interrupt'; procedure QEI0_Interrupt; external name 'QEI0_Interrupt'; procedure ADC0_Sequence_0_Interrupt; external name 'ADC0_Sequence_0_Interrupt'; procedure ADC0_Sequence_1_Interrupt; external name 'ADC0_Sequence_1_Interrupt'; @@ -99,6 +112,7 @@ procedure Timer_2A_Interrupt; external name 'Timer_2A_Interrupt'; procedure Timer_2B_Interrupt; external name 'Timer_2B_Interrupt'; procedure Analog_Comparator_0_Interrupt; external name 'Analog_Comparator_0_Interrupt'; procedure Analog_Comparator_1_Interrupt; external name 'Analog_Comparator_1_Interrupt'; +procedure Analog_Comparator_2_Interrupt; external name 'Analog_Comparator_2_Interrupt'; procedure System_Control_Interrupt; external name 'System_Control_Interrupt'; procedure Flash_Memory_Control_Interrupt; external name 'Flash_Memory_Control_Interrupt'; procedure GPIO_Port_F_Interrupt; external name 'GPIO_Port_F_Interrupt'; @@ -112,6 +126,7 @@ procedure I2C1_Interrupt; external name 'I2C1_Interrupt'; procedure QEI1_Interrupt; external name 'QEI1_Interrupt'; procedure CAN0_Interrupt; external name 'CAN0_Interrupt'; procedure CAN1_Interrupt; external name 'CAN1_Interrupt'; +procedure ETH_Interrupt; external name 'ETH_Interrupt'; procedure Hibernation_Module_Interrupt; external name 'Hibernation_Module_Interrupt'; procedure USB_Interrupt; external name 'USB_Interrupt'; procedure uDMA_Software_Interrupt; external name 'uDMA_Software_Interrupt'; @@ -121,6 +136,7 @@ procedure ADC1_Sequence_1_Interrupt; external name 'ADC1_Sequence_1_Interrupt'; procedure ADC1_Sequence_2_Interrupt; external name 'ADC1_Sequence_2_Interrupt'; procedure ADC1_Sequence_3_Interrupt; external name 'ADC1_Sequence_3_Interrupt'; procedure I2S0_Interrupt; external name 'I2S0_Interrupt'; +procedure EPI_interrupt; external name 'EPI_Interrupt'; procedure GPIO_Port_J_Interrupt; external name 'GPIO_Port_J_Interrupt'; {$i cortexm3_start.inc} @@ -174,7 +190,7 @@ interrupt_vectors: .long Timer_2B_Interrupt .long Analog_Comparator_0_Interrupt .long Analog_Comparator_1_Interrupt - .long 0 + .long Analog_Comparator_2_Interrupt .long System_Control_Interrupt .long Flash_Memory_Control_Interrupt .long GPIO_Port_F_Interrupt @@ -189,10 +205,10 @@ interrupt_vectors: .long CAN0_Interrupt .long CAN1_Interrupt .long 0 - .long 0 + .long ETH_Interrupt .long Hibernation_Module_Interrupt .long USB_Interrupt - .long 0 + .long PWM_Generator_3_Interrupt .long uDMA_Software_Interrupt .long uDMA_Error_Interrupt .long ADC1_Sequence_0_Interrupt @@ -200,7 +216,7 @@ interrupt_vectors: .long ADC1_Sequence_2_Interrupt .long ADC1_Sequence_3_Interrupt .long I2S0_Interrupt - .long 0 + .long EPI_Interrupt .long GPIO_Port_J_Interrupt .weak NMI_interrupt @@ -226,6 +242,7 @@ interrupt_vectors: .weak PWM_Generator_0_Interrupt .weak PWM_Generator_1_Interrupt .weak PWM_Generator_2_Interrupt + .weak PWM_Generator_3_Interrupt .weak QEI0_Interrupt .weak ADC0_Sequence_0_Interrupt .weak ADC0_Sequence_1_Interrupt @@ -240,6 +257,7 @@ interrupt_vectors: .weak Timer_2B_Interrupt .weak Analog_Comparator_0_Interrupt .weak Analog_Comparator_1_Interrupt + .weak Analog_Comparator_2_Interrupt .weak System_Control_Interrupt .weak Flash_Memory_Control_Interrupt .weak GPIO_Port_F_Interrupt @@ -253,6 +271,7 @@ interrupt_vectors: .weak QEI1_Interrupt .weak CAN0_Interrupt .weak CAN1_Interrupt + .weak ETH_Interrupt .weak Hibernation_Module_Interrupt .weak USB_Interrupt .weak uDMA_Software_Interrupt @@ -262,68 +281,73 @@ interrupt_vectors: .weak ADC1_Sequence_2_Interrupt .weak ADC1_Sequence_3_Interrupt .weak I2S0_Interrupt + .weak EPI_Interrupt .weak GPIO_Port_J_Interrupt - .set NMI_interrupt, Startup - .set Hardfault_interrupt, Startup - .set MemManage_interrupt, Startup - .set BusFault_interrupt, Startup - .set UsageFault_interrupt, Startup - .set SWI_interrupt, Startup - .set DebugMonitor_interrupt, Startup - .set PendingSV_interrupt, Startup - .set SysTick_interrupt, Startup + .set NMI_interrupt, haltproc + .set Hardfault_interrupt, haltproc + .set MemManage_interrupt, haltproc + .set BusFault_interrupt, haltproc + .set UsageFault_interrupt, haltproc + .set SWI_interrupt, haltproc + .set DebugMonitor_interrupt, haltproc + .set PendingSV_interrupt, haltproc + .set SysTick_interrupt, haltproc - .set GPIO_Port_A_Interrupt, Startup - .set GPIO_Port_B_Interrupt, Startup - .set GPIO_Port_C_Interrupt, Startup - .set GPIO_Port_D_Interrupt, Startup - .set GPIO_Port_E_Interrupt, Startup - .set UART0_Interrupt, Startup - .set UART1_Interrupt, Startup - .set SSI0_Interrupt, Startup - .set I2C0_Interrupt, Startup - .set PWM_Fault_Interrupt, Startup - .set PWM_Generator_0_Interrupt, Startup - .set PWM_Generator_1_Interrupt, Startup - .set PWM_Generator_2_Interrupt, Startup - .set QEI0_Interrupt, Startup - .set ADC0_Sequence_0_Interrupt, Startup - .set ADC0_Sequence_1_Interrupt, Startup - .set ADC0_Sequence_2_Interrupt, Startup - .set ADC0_Sequence_3_Interrupt, Startup - .set Watchdog_Timers_0_and_1_Interrupt, Startup - .set Timer_0A_Interrupt, Startup - .set Timer_0B_Interrupt, Startup - .set Timer_1A_Interrupt, Startup - .set Timer_1B_Interrupt, Startup - .set Timer_2A_Interrupt, Startup - .set Timer_2B_Interrupt, Startup - .set Analog_Comparator_0_Interrupt, Startup - .set Analog_Comparator_1_Interrupt, Startup - .set System_Control_Interrupt, Startup - .set Flash_Memory_Control_Interrupt, Startup - .set GPIO_Port_F_Interrupt, Startup - .set GPIO_Port_G_Interrupt, Startup - .set GPIO_Port_H_Interrupt, Startup - .set UART2_Interrupt, Startup - .set SSI1_Interrupt, Startup - .set Timer_3A_Interrupt, Startup - .set Timer_3B_Interrupt, Startup - .set I2C1_Interrupt, Startup - .set QEI1_Interrupt, Startup - .set CAN0_Interrupt, Startup - .set CAN1_Interrupt, Startup - .set Hibernation_Module_Interrupt, Startup - .set USB_Interrupt, Startup - .set uDMA_Software_Interrupt, Startup - .set uDMA_Error_Interrupt, Startup - .set ADC1_Sequence_0_Interrupt, Startup - .set ADC1_Sequence_1_Interrupt, Startup - .set ADC1_Sequence_2_Interrupt, Startup - .set ADC1_Sequence_3_Interrupt, Startup - .set I2S0_Interrupt, Startup - .set GPIO_Port_J_Interrupt, Startup + .set GPIO_Port_A_Interrupt, haltproc + .set GPIO_Port_B_Interrupt, haltproc + .set GPIO_Port_C_Interrupt, haltproc + .set GPIO_Port_D_Interrupt, haltproc + .set GPIO_Port_E_Interrupt, haltproc + .set UART0_Interrupt, haltproc + .set UART1_Interrupt, haltproc + .set SSI0_Interrupt, haltproc + .set I2C0_Interrupt, haltproc + .set PWM_Fault_Interrupt, haltproc + .set PWM_Generator_0_Interrupt, haltproc + .set PWM_Generator_1_Interrupt, haltproc + .set PWM_Generator_2_Interrupt, haltproc + .set PWM_Generator_3_Interrupt, haltproc + .set QEI0_Interrupt, haltproc + .set ADC0_Sequence_0_Interrupt, haltproc + .set ADC0_Sequence_1_Interrupt, haltproc + .set ADC0_Sequence_2_Interrupt, haltproc + .set ADC0_Sequence_3_Interrupt, haltproc + .set Watchdog_Timers_0_and_1_Interrupt, haltproc + .set Timer_0A_Interrupt, haltproc + .set Timer_0B_Interrupt, haltproc + .set Timer_1A_Interrupt, haltproc + .set Timer_1B_Interrupt, haltproc + .set Timer_2A_Interrupt, haltproc + .set Timer_2B_Interrupt, haltproc + .set Analog_Comparator_0_Interrupt, haltproc + .set Analog_Comparator_1_Interrupt, haltproc + .set Analog_Comparator_2_Interrupt, haltproc + .set System_Control_Interrupt, haltproc + .set Flash_Memory_Control_Interrupt, haltproc + .set GPIO_Port_F_Interrupt, haltproc + .set GPIO_Port_G_Interrupt, haltproc + .set GPIO_Port_H_Interrupt, haltproc + .set UART2_Interrupt, haltproc + .set SSI1_Interrupt, haltproc + .set Timer_3A_Interrupt, haltproc + .set Timer_3B_Interrupt, haltproc + .set I2C1_Interrupt, haltproc + .set QEI1_Interrupt, haltproc + .set CAN0_Interrupt, haltproc + .set CAN1_Interrupt, haltproc + .set ETH_Interrupt, haltproc + .set Hibernation_Module_Interrupt, haltproc + .set USB_Interrupt, haltproc + .set uDMA_Software_Interrupt, haltproc + .set uDMA_Error_Interrupt, haltproc + .set ADC1_Sequence_0_Interrupt, haltproc + .set ADC1_Sequence_1_Interrupt, haltproc + .set ADC1_Sequence_2_Interrupt, haltproc + .set ADC1_Sequence_3_Interrupt, haltproc + .set I2S0_Interrupt, haltproc + .set EPI_Interrupt, haltproc + .set GPIO_Port_J_Interrupt, haltproc .text end;