|
@@ -770,6 +770,20 @@ unit cgcpu;
|
|
|
so.shiftimm:=l1;
|
|
|
list.concat(taicpu.op_reg_reg_reg_shifterop(A_ADD,dst,src,src,so));
|
|
|
end
|
|
|
+ { for example : b=a*7 -> b=a*8-a with rsb instruction and shl }
|
|
|
+ else if (op in [OP_MUL,OP_IMUL]) and ispowerof2(a+1,l1) and not(cgsetflags or setflags) then
|
|
|
+ begin
|
|
|
+ if l1>32 then{does this ever happen?}
|
|
|
+ internalerror(201205181);
|
|
|
+ shifterop_reset(so);
|
|
|
+ so.shiftmode:=SM_LSL;
|
|
|
+ so.shiftimm:=l1;
|
|
|
+ list.concat(taicpu.op_reg_reg_reg_shifterop(A_RSB,dst,src,src,so));
|
|
|
+ end
|
|
|
+ { BIC clears the specified bits, while AND keeps them, using BIC allows to use a
|
|
|
+ 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))))
|
|
|
else
|
|
|
begin
|
|
|
tmpreg:=getintregister(list,size);
|