diff --git a/compiler/nmat.pas b/compiler/nmat.pas index dfc09eefb7..b75dcc5966 100644 --- a/compiler/nmat.pas +++ b/compiler/nmat.pas @@ -573,16 +573,44 @@ implementation ****************************************************************************} function tshlshrnode.simplify(forinline : boolean):tnode; + var + lvalue,rvalue : Tconstexprint; begin result:=nil; { constant folding } if is_constintnode(left) and is_constintnode(right) then begin + { x86 wraps around } + { shl/shr are unsigned operations, so cut off upper bits } + case resultdef.size of + 1: + begin + rvalue:=tordconstnode(right).value and byte($7); + lvalue:=tordconstnode(left).value and byte($ff); + end; + 2: + begin + rvalue:=tordconstnode(right).value and byte($f); + lvalue:=tordconstnode(left).value and word($ffff); + end; + 4: + begin + rvalue:=tordconstnode(right).value and byte($1f); + lvalue:=tordconstnode(left).value and dword($ffffffff); + end; + 8: + begin + rvalue:=tordconstnode(right).value and byte($3f); + lvalue:=tordconstnode(left).value and qword($ffffffffffffffff); + end; + else + internalerror(2013122301); + end; case nodetype of shrn: - result:=create_simplified_ord_const(tordconstnode(left).value shr tordconstnode(right).value,resultdef,forinline); + result:=create_simplified_ord_const(lvalue shr rvalue,resultdef,forinline); shln: - result:=create_simplified_ord_const(tordconstnode(left).value shl tordconstnode(right).value,resultdef,forinline); + result:=create_simplified_ord_const(lvalue shl rvalue,resultdef,forinline); end; end; end; diff --git a/tests/tbs/tb0295.pp b/tests/tbs/tb0295.pp index 0fe270016d..b12a6c6b94 100644 --- a/tests/tbs/tb0295.pp +++ b/tests/tbs/tb0295.pp @@ -11,7 +11,7 @@ Var begin I:=2; Writeln(i); - K:=1 shl 62; + K:=qword(1) shl 62; For j:=1 to 61 do begin I:=I*2; diff --git a/tests/webtbs/tw16328.pp b/tests/webtbs/tw16328.pp index 1cec8914ef..04c086c966 100644 --- a/tests/webtbs/tw16328.pp +++ b/tests/webtbs/tw16328.pp @@ -10,7 +10,7 @@ const type TmydbID = type Longword; TmydbCLSID = type Word; - TmydbDBID = 0..(1 shl 48)-1; // Unique ID of the database + TmydbDBID = 0..(qword(1) shl 48)-1; // Unique ID of the database TmydbDBTYPE = type Byte; tarr = bitpacked array[0..10] of TmydbDBID; diff --git a/tests/webtbs/tw22133.pp b/tests/webtbs/tw22133.pp index 80a82b048c..bf46d6e7e3 100644 --- a/tests/webtbs/tw22133.pp +++ b/tests/webtbs/tw22133.pp @@ -19,7 +19,7 @@ begin end; begin - T64:=UInt64(1 shl 63); + T64:=UInt64(qword(1) shl 63); if T64<>uint64(high(int64)+1) then halt(1); T64:=UInt64(1) shl 63;