summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-01-20 14:57:38 +0000
committerflorian <florian@3ad0048d-3df7-0310-abae-a5850022a9f2>2013-01-20 14:57:38 +0000
commit6646524b6d69a0489a57324a0c087db2c21f5ea1 (patch)
tree8733313367bbfa171e957936b0bfdc1d9baa2875
parenta38c23f129c4a069355fa347e5ed136bc822a7d5 (diff)
downloadfpc-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.pas66
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