|
@@ -683,7 +683,9 @@ implementation
|
|
|
|
|
|
function tshlshrnode.simplify(forinline : boolean):tnode;
|
|
function tshlshrnode.simplify(forinline : boolean):tnode;
|
|
var
|
|
var
|
|
- lvalue,rvalue : Tconstexprint;
|
|
|
|
|
|
+ lvalue, rvalue, mask : Tconstexprint;
|
|
|
|
+ rangedef: tdef;
|
|
|
|
+ size: longint;
|
|
begin
|
|
begin
|
|
result:=nil;
|
|
result:=nil;
|
|
{ constant folding }
|
|
{ constant folding }
|
|
@@ -691,7 +693,6 @@ implementation
|
|
begin
|
|
begin
|
|
if forinline then
|
|
if forinline then
|
|
begin
|
|
begin
|
|
- { shl/shr are unsigned operations, so cut off upper bits }
|
|
|
|
case resultdef.size of
|
|
case resultdef.size of
|
|
1,2,4:
|
|
1,2,4:
|
|
rvalue:=tordconstnode(right).value and byte($1f);
|
|
rvalue:=tordconstnode(right).value and byte($1f);
|
|
@@ -706,19 +707,10 @@ implementation
|
|
if is_constintnode(left) then
|
|
if is_constintnode(left) then
|
|
begin
|
|
begin
|
|
lvalue:=tordconstnode(left).value;
|
|
lvalue:=tordconstnode(left).value;
|
|
- { shl/shr are unsigned operations, so cut off upper bits }
|
|
|
|
- case resultdef.size of
|
|
|
|
- 1:
|
|
|
|
- lvalue:=lvalue and byte($ff);
|
|
|
|
- 2:
|
|
|
|
- lvalue:=lvalue and word($ffff);
|
|
|
|
- 4:
|
|
|
|
- lvalue:=lvalue and dword($ffffffff);
|
|
|
|
- 8:
|
|
|
|
- lvalue:=lvalue and qword($ffffffffffffffff);
|
|
|
|
- else
|
|
|
|
- internalerror(2013122301);
|
|
|
|
- end;
|
|
|
|
|
|
+ getrangedefmasksize(resultdef, rangedef, mask, size);
|
|
|
|
+ { shr is an unsigned operation, so cut off upper bits }
|
|
|
|
+ if forinline then
|
|
|
|
+ lvalue:=lvalue and mask;
|
|
case nodetype of
|
|
case nodetype of
|
|
shrn:
|
|
shrn:
|
|
lvalue:=lvalue shr rvalue;
|
|
lvalue:=lvalue shr rvalue;
|
|
@@ -730,20 +722,7 @@ implementation
|
|
{ discard shifted-out bits (shl never triggers overflow/range errors) }
|
|
{ discard shifted-out bits (shl never triggers overflow/range errors) }
|
|
if forinline and
|
|
if forinline and
|
|
(nodetype=shln) then
|
|
(nodetype=shln) then
|
|
- begin
|
|
|
|
- case resultdef.size of
|
|
|
|
- 1:
|
|
|
|
- lvalue:=lvalue and byte($ff);
|
|
|
|
- 2:
|
|
|
|
- lvalue:=lvalue and word($ffff);
|
|
|
|
- 4:
|
|
|
|
- lvalue:=lvalue and dword($ffffffff);
|
|
|
|
- 8:
|
|
|
|
- lvalue:=lvalue and qword($ffffffffffffffff);
|
|
|
|
- else
|
|
|
|
- internalerror(2019111701);
|
|
|
|
- end;
|
|
|
|
- end;
|
|
|
|
|
|
+ lvalue:=lvalue and mask;
|
|
result:=create_simplified_ord_const(lvalue,resultdef,forinline,false);
|
|
result:=create_simplified_ord_const(lvalue,resultdef,forinline,false);
|
|
end
|
|
end
|
|
else if rvalue=0 then
|
|
else if rvalue=0 then
|
|
@@ -757,19 +736,8 @@ implementation
|
|
lvalue:=tordconstnode(left).value;
|
|
lvalue:=tordconstnode(left).value;
|
|
if forinline then
|
|
if forinline then
|
|
begin
|
|
begin
|
|
- { shl/shr are unsigned operations, so cut off upper bits }
|
|
|
|
- case resultdef.size of
|
|
|
|
- 1:
|
|
|
|
- lvalue:=tordconstnode(left).value and byte($ff);
|
|
|
|
- 2:
|
|
|
|
- lvalue:=tordconstnode(left).value and word($ffff);
|
|
|
|
- 4:
|
|
|
|
- lvalue:=tordconstnode(left).value and dword($ffffffff);
|
|
|
|
- 8:
|
|
|
|
- lvalue:=tordconstnode(left).value and qword($ffffffffffffffff);
|
|
|
|
- else
|
|
|
|
- internalerror(2013122301);
|
|
|
|
- end;
|
|
|
|
|
|
+ getrangedefmasksize(resultdef, rangedef, mask, size);
|
|
|
|
+ lvalue:=lvalue and mask;
|
|
end;
|
|
end;
|
|
{ '0 shl x' and '0 shr x' are 0 }
|
|
{ '0 shl x' and '0 shr x' are 0 }
|
|
if (lvalue=0) and
|
|
if (lvalue=0) and
|