diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-01-20 14:57:43 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-01-20 14:57:43 +0000 |
commit | 533d2bb382e028368689ab4ed5b69d73901453fe (patch) | |
tree | 5431ae4e3692c47bcb92d771a4a57323192eb8eb | |
parent | 6646524b6d69a0489a57324a0c087db2c21f5ea1 (diff) | |
download | fpc-533d2bb382e028368689ab4ed5b69d73901453fe.tar.gz |
* improve ShiftShiftShift2ShiftShift to look further ahead
* check register usage so the destination register can be different
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@23457 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | compiler/arm/aoptcpu.pas | 45 |
1 files changed, 31 insertions, 14 deletions
diff --git a/compiler/arm/aoptcpu.pas b/compiler/arm/aoptcpu.pas index 7af0dc6a61..46074bf48e 100644 --- a/compiler/arm/aoptcpu.pas +++ b/compiler/arm/aoptcpu.pas @@ -764,38 +764,55 @@ Implementation mov reg1,reg1, shift imm2 mov reg1,reg1, shift imm3 ... } - else if getnextinstruction(hp1,hp2) and + else if GetNextInstructionUsingReg(hp1,hp2, taicpu(p).oper[0]^.reg) and + (assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp2.Next))) or + regLoadedWithNewValue(taicpu(p).oper[0]^.reg, hp2)) and MatchInstruction(hp2, A_MOV, [taicpu(p).condition], [PF_None]) and (taicpu(hp2).ops=3) and - MatchOperand(taicpu(hp2).oper[0]^, taicpu(hp1).oper[0]^.reg) and MatchOperand(taicpu(hp2).oper[1]^, taicpu(hp1).oper[0]^.reg) and (taicpu(hp2).oper[2]^.typ = top_shifterop) and (taicpu(hp2).oper[2]^.shifterop^.rs = NR_NO) then begin { mov reg1,reg0, lsl imm1 mov reg1,reg1, lsr/asr imm2 - mov reg1,reg1, lsl imm3 ... - - if imm3<=imm1 and imm2>=imm3 + mov reg2,reg1, lsl imm3 ... to mov reg1,reg0, lsl imm1 - mov reg1,reg1, lsr/asr imm2-imm3 + mov reg2,reg1, lsr/asr imm2-imm3 + if + imm1>=imm2 } if (taicpu(p).oper[2]^.shifterop^.shiftmode=SM_LSL) and (taicpu(hp2).oper[2]^.shifterop^.shiftmode=SM_LSL) and (taicpu(hp1).oper[2]^.shifterop^.shiftmode in [SM_ASR,SM_LSR]) and - (taicpu(hp2).oper[2]^.shifterop^.shiftimm<=taicpu(p).oper[2]^.shifterop^.shiftimm) and - (taicpu(hp1).oper[2]^.shifterop^.shiftimm>=taicpu(hp2).oper[2]^.shifterop^.shiftimm) then + (taicpu(p).oper[2]^.shifterop^.shiftimm>=taicpu(hp1).oper[2]^.shifterop^.shiftimm) then begin - dec(taicpu(hp1).oper[2]^.shifterop^.shiftimm,taicpu(hp2).oper[2]^.shifterop^.shiftimm); - DebugMsg('Peephole ShiftShiftShift2ShiftShift 1 done', p); - asml.remove(hp2); - hp2.free; - result := true; - if taicpu(hp1).oper[2]^.shifterop^.shiftimm=0 then + if taicpu(hp2).oper[2]^.shifterop^.shiftimm>=taicpu(hp1).oper[2]^.shifterop^.shiftimm then begin + DebugMsg('Peephole ShiftShiftShift2ShiftShift 1a done', p); + inc(taicpu(p).oper[2]^.shifterop^.shiftimm,taicpu(hp2).oper[2]^.shifterop^.shiftimm-taicpu(hp1).oper[2]^.shifterop^.shiftimm); + taicpu(p).oper[0]^.reg:=taicpu(hp2).oper[0]^.reg; asml.remove(hp1); + asml.remove(hp2); hp1.free; + hp2.free; + + if taicpu(hp1).oper[2]^.shifterop^.shiftimm>=32 then + begin + taicpu(p).freeop(1); + taicpu(p).freeop(2); + taicpu(p).loadconst(1,0); + end; + end + else + begin + DebugMsg('Peephole ShiftShiftShift2ShiftShift 1b done', p); + + dec(taicpu(hp1).oper[2]^.shifterop^.shiftimm,taicpu(hp2).oper[2]^.shifterop^.shiftimm); + taicpu(hp1).oper[0]^.reg:=taicpu(hp2).oper[0]^.reg; + asml.remove(hp2); + hp2.free; end; + result := true; end { mov reg1,reg0, lsr/asr imm1 mov reg1,reg1, lsl imm2 |