|
@@ -213,7 +213,29 @@ unit cgcpu;
|
|
|
OP_SHR,OP_SHL,OP_SAR:
|
|
|
begin
|
|
|
a:=a and 31;
|
|
|
- if a<>0 then
|
|
|
+ { for shl with const >= 16, we can just move the low register
|
|
|
+ to the high reg, then zero the low register, then do the
|
|
|
+ remaining part of the shift (by const-16) in 16 bit on the
|
|
|
+ high register. the same thing applies to shr with low and high
|
|
|
+ reversed. }
|
|
|
+ if (op in [OP_SHR,OP_SHL]) and (a >= 16) then
|
|
|
+ case op of
|
|
|
+ OP_SHR:
|
|
|
+ begin
|
|
|
+ a_load_reg_reg(list,OS_16,OS_16,GetNextReg(reg),reg);
|
|
|
+ a_load_const_reg(list,OS_16,0,GetNextReg(reg));
|
|
|
+ a_op_const_reg(list,OP_SHR,OS_16,a-16,reg);
|
|
|
+ end;
|
|
|
+ OP_SHL:
|
|
|
+ begin
|
|
|
+ a_load_reg_reg(list,OS_16,OS_16,reg,GetNextReg(reg));
|
|
|
+ a_load_const_reg(list,OS_16,0,reg);
|
|
|
+ a_op_const_reg(list,OP_SHL,OS_16,a-16,GetNextReg(reg));
|
|
|
+ end;
|
|
|
+ else
|
|
|
+ internalerror(2013060201);
|
|
|
+ end
|
|
|
+ else if a<>0 then
|
|
|
begin
|
|
|
use_loop:=a>2;
|
|
|
|