From 0736bf4dede42a454538bb53a7011d4442599e56 Mon Sep 17 00:00:00 2001 From: masta Date: Wed, 22 Jan 2014 20:21:02 +0000 Subject: [PATCH] Try to change typical constant AND-masking operations into shifts for ARM If the constant only contains a string of ones starting from lsb or msb we can shift out the bits accordingly, opening up some possibilities for the peephole optimizer to fold at least one shift into another operation. git-svn-id: trunk@26565 - --- compiler/arm/cgcpu.pas | 26 +++++++++++++++++++++++++- 1 file changed, 25 insertions(+), 1 deletion(-) diff --git a/compiler/arm/cgcpu.pas b/compiler/arm/cgcpu.pas index 9206d75b7b..26f7e12e5e 100644 --- a/compiler/arm/cgcpu.pas +++ b/compiler/arm/cgcpu.pas @@ -894,7 +894,7 @@ unit cgcpu; procedure tcgarm.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, lsb, width : byte; tmpreg : tregister; so : tshifterop; l1 : longint; @@ -1015,6 +1015,30 @@ unit cgcpu; broader range of shifterconstants.} else if (op = OP_AND) and is_shifter_const(not(dword(a)),shift) then list.concat(taicpu.op_reg_reg_const(A_BIC,dst,src,not(dword(a)))) + { Doing two shifts instead of two bics might allow the peephole optimizer to fold the second shift + into the following instruction} + else if (op = OP_AND) and + is_continuous_mask(a, lsb, width) and + ((lsb = 0) or ((lsb + width) = 32)) then + begin + shifterop_reset(so); + if lsb = 0 then + begin + so.shiftmode:=SM_LSL; + so.shiftimm:=32-width; + list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so)); + so.shiftmode:=SM_LSR; + list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,dst,so)); + end + else + begin + so.shiftmode:=SM_LSR; + so.shiftimm:=lsb; + list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,src,so)); + so.shiftmode:=SM_LSL; + list.concat(taicpu.op_reg_reg_shifterop(A_MOV,dst,dst,so)); + end; + end else if (op = OP_AND) and split_into_shifter_const(not(dword(a)), imm1, imm2) then begin list.concat(taicpu.op_reg_reg_const(A_BIC,dst,src,imm1));