diff options
author | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-01-20 14:57:38 +0000 |
---|---|---|
committer | florian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2> | 2013-01-20 14:57:38 +0000 |
commit | 6646524b6d69a0489a57324a0c087db2c21f5ea1 (patch) | |
tree | 8733313367bbfa171e957936b0bfdc1d9baa2875 | |
parent | a38c23f129c4a069355fa347e5ed136bc822a7d5 (diff) | |
download | fpc-6646524b6d69a0489a57324a0c087db2c21f5ea1.tar.gz |
* remove bic instructions after lsr if possible
git-svn-id: http://svn.freepascal.org/svn/fpc/trunk@23456 3ad0048d-3df7-0310-abae-a5850022a9f2
-rw-r--r-- | compiler/arm/aoptcpu.pas | 66 |
1 files changed, 41 insertions, 25 deletions
diff --git a/compiler/arm/aoptcpu.pas b/compiler/arm/aoptcpu.pas index 9c7944240f..7af0dc6a61 100644 --- a/compiler/arm/aoptcpu.pas +++ b/compiler/arm/aoptcpu.pas @@ -829,10 +829,10 @@ Implementation end; end; { Change the common - mov r0, r0, lsr #24 - and r0, r0, #255 + mov r0, r0, lsr #xxx + and r0, r0, #yyy/bic r0, r0, #xxx - and remove the superfluous and + and remove the superfluous and/bic if possible This could be extended to handle more cases. } @@ -840,30 +840,46 @@ Implementation (taicpu(p).oper[2]^.typ = top_shifterop) and (taicpu(p).oper[2]^.shifterop^.rs = NR_NO) and (taicpu(p).oper[2]^.shifterop^.shiftmode = SM_LSR) and - (taicpu(p).oper[2]^.shifterop^.shiftimm >= 24 ) and GetNextInstructionUsingReg(p,hp1, taicpu(p).oper[0]^.reg) and (assigned(FindRegDealloc(taicpu(p).oper[0]^.reg,tai(hp1.Next))) or - regLoadedWithNewValue(taicpu(p).oper[0]^.reg, hp1)) and - MatchInstruction(hp1, A_AND, [taicpu(p).condition], [taicpu(p).oppostfix]) and - (taicpu(hp1).ops=3) and - MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[0]^) and - MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[1]^) and - (taicpu(hp1).oper[2]^.typ = top_const) and - { Check if the AND actually would only mask out bits beeing already zero because of the shift - For LSR #25 and an AndConst of 255 that whould go like this: - 255 and ((2 shl (32-25))-1) - which results in 127, which is one less a power-of-2, meaning all lower bits are set. - - LSR #25 and AndConst of 254: - 254 and ((2 shl (32-25))-1) = 126 -> lowest bit is clear, so we can't remove it. - } - ispowerof2((taicpu(hp1).oper[2]^.val and ((2 shl (32-taicpu(p).oper[2]^.shifterop^.shiftimm))-1))+1) then - begin - DebugMsg('Peephole LsrAnd2Lsr done', hp1); - asml.remove(hp1); - hp1.free; - result:=true; - end; + regLoadedWithNewValue(taicpu(p).oper[0]^.reg, hp1)) then + begin + if (taicpu(p).oper[2]^.shifterop^.shiftimm >= 24 ) and + MatchInstruction(hp1, A_AND, [taicpu(p).condition], [taicpu(p).oppostfix]) and + (taicpu(hp1).ops=3) and + MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[1]^) and + (taicpu(hp1).oper[2]^.typ = top_const) and + { Check if the AND actually would only mask out bits beeing already zero because of the shift + For LSR #25 and an AndConst of 255 that whould go like this: + 255 and ((2 shl (32-25))-1) + which results in 127, which is one less a power-of-2, meaning all lower bits are set. + + LSR #25 and AndConst of 254: + 254 and ((2 shl (32-25))-1) = 126 -> lowest bit is clear, so we can't remove it. + } + ispowerof2((taicpu(hp1).oper[2]^.val and ((2 shl (32-taicpu(p).oper[2]^.shifterop^.shiftimm))-1))+1) then + begin + DebugMsg('Peephole LsrAnd2Lsr done', hp1); + taicpu(p).oper[0]^.reg:=taicpu(hp1).oper[0]^.reg; + asml.remove(hp1); + hp1.free; + result:=true; + end + else if MatchInstruction(hp1, A_BIC, [taicpu(p).condition], [taicpu(p).oppostfix]) and + (taicpu(hp1).ops=3) and + MatchOperand(taicpu(p).oper[0]^, taicpu(hp1).oper[1]^) and + (taicpu(hp1).oper[2]^.typ = top_const) and + { Check if the BIC actually would only mask out bits beeing already zero because of the shift } + (taicpu(hp1).oper[2]^.val<>0) and + (BsfDWord(taicpu(hp1).oper[2]^.val)>=32-taicpu(p).oper[2]^.shifterop^.shiftimm) then + begin + DebugMsg('Peephole LsrBic2Lsr done', hp1); + taicpu(p).oper[0]^.reg:=taicpu(hp1).oper[0]^.reg; + asml.remove(hp1); + hp1.free; + result:=true; + end; + end; { optimize |