diff --git a/.travis.yml b/.travis.yml index fe1494196f..15b6d97b30 100644 --- a/.travis.yml +++ b/.travis.yml @@ -5,21 +5,49 @@ sudo: required matrix: include: - os: linux - env: CC=gcc MLTON_COMPILE_ARGS="-codegen amd64" REGRESSION=true + dist: trusty + addons: + apt: + update: true + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-5 + - mlton + env: CC=gcc-5 MLTON_COMPILE_ARGS="-codegen amd64" REGRESSION=true - os: linux - env: CC=gcc MLTON_COMPILE_ARGS="-codegen c" REGRESSION=false + dist: trusty + addons: + apt: + update: true + sources: + - ubuntu-toolchain-r-test + packages: + - gcc-5 + - mlton + env: CC=gcc-5 MLTON_COMPILE_ARGS="-codegen c" REGRESSION=false - os: linux - env: CC=clang MLTON_COMPILE_ARGS="-codegen c" REGRESSION=false + dist: trusty + addons: + apt: + update: true + packages: + - mlton + env: CC=clang MLTON_COMPILE_ARGS="-codegen c" REGRESSION=false - os: linux - env: CC=clang MLTON_COMPILE_ARGS="-codegen llvm" REGRESSION=false + dist: trusty + addons: + apt: + update: true + packages: + - mlton + env: CC=clang MLTON_COMPILE_ARGS="-codegen llvm" REGRESSION=false - os: osx - env: CC=clang MLTON_COMPILE_ARGS="-codegen amd64" REGRESSION=false + env: CC=clang MLTON_COMPILE_ARGS="-codegen amd64" REGRESSION=false - os: osx - env: CC=clang MLTON_COMPILE_ARGS="-codegen c" REGRESSION=false + env: CC=clang MLTON_COMPILE_ARGS="-codegen c" REGRESSION=false install: - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get -qq update; fi - - if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then sudo apt-get install -qq mlton; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew update; fi - if [[ "$TRAVIS_OS_NAME" == "osx" ]]; then brew install mlton; fi diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index 22bf6a3c87..74d22b1693 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -8,6 +8,10 @@ Here are the changes from versoin 20180206 to version YYYYMMDD. === Details +* 2018-10-15 + ** Introduce new `Overflow`-checking primitives. Undertaken by Daman Morris + at RIT supported by NSF CISE Research Infrastructure (CRI) award. + * 2018-08-17 ** Add a parser for the SSA2 IR (`functor ParseSsa2`). Undertaken by Manan Joshi at RIT supported by NSF CISE Research Infrastructure (CRI) award. diff --git a/basis-library/arrays-and-vectors/array2.sml b/basis-library/arrays-and-vectors/array2.sml index a8a91e5826..bbd4688892 100644 --- a/basis-library/arrays-and-vectors/array2.sml +++ b/basis-library/arrays-and-vectors/array2.sml @@ -10,11 +10,11 @@ structure Array2 : ARRAY2 = struct - val op +? = SeqIndex.+? + val op +! = SeqIndex.+! val op + = SeqIndex.+ - val op -? = SeqIndex.-? + val op -! = SeqIndex.-! val op - = SeqIndex.- - val op *? = SeqIndex.*? + val op *! = SeqIndex.*! val op * = SeqIndex.* val op < = SeqIndex.< val op <= = SeqIndex.<= @@ -66,12 +66,12 @@ structure Array2 : ARRAY2 = handle Overflow => raise Subscript in if (start < 0 orelse num < 0 - orelse start +? num > max) + orelse start +! num > max) then raise Subscript - else (start, start +? num) + else (start, start +! num) end else (SeqIndex.fromIntUnsafe start, - SeqIndex.fromIntUnsafe start +? num) + SeqIndex.fromIntUnsafe start +! num) fun checkSliceMax (start: int, num: int option, max: SeqIndex.int): SeqIndex.int * SeqIndex.int = @@ -147,7 +147,7 @@ structure Array2 : ARRAY2 = cols = 0} fun unsafeSpot' ({cols, ...}: 'a array, r, c) = - r *? cols +? c + r *! cols +! c fun spot' (a as {rows, cols, ...}: 'a array, r, c) = if Primitive.Controls.safe andalso (geu (r, rows) orelse geu (c, cols)) @@ -197,13 +197,13 @@ structure Array2 : ARRAY2 = List.foldl (fn (row: 'a list, i) => let - val max = i +? cols' + val max = i +! cols' val i' = List.foldl (fn (x: 'a, i) => (if i >= max then raise Size else (Primitive.Array.unsafeUpdate (array, i, x) - ; i +? 1))) + ; i +! 1))) i row in if i' = max then i' @@ -218,7 +218,7 @@ structure Array2 : ARRAY2 = if Primitive.Controls.safe andalso geu (r, rows) then raise Subscript else - ArraySlice.vector (Primitive.Array.Slice.slice (array, r *? cols, SOME cols)) + ArraySlice.vector (Primitive.Array.Slice.slice (array, r *! cols, SOME cols)) fun row (a, r) = if Primitive.Controls.safe then let @@ -257,9 +257,9 @@ structure Array2 : ARRAY2 = else let fun loopCol (c, b) = if c >= stopCol then b - else loopCol (c +? 1, f (r, c, sub' (base, r, c), b)) + else loopCol (c +! 1, f (r, c, sub' (base, r, c), b)) in - loopRow (r +? 1, loopCol (startCol, b)) + loopRow (r +! 1, loopCol (startCol, b)) end in loopRow (startRow, b) @@ -271,9 +271,9 @@ structure Array2 : ARRAY2 = else let fun loopRow (r, b) = if r >= stopRow then b - else loopRow (r +? 1, f (r, c, sub' (base, r, c), b)) + else loopRow (r +! 1, f (r, c, sub' (base, r, c), b)) in - loopCol (c +? 1, loopRow (startRow, b)) + loopCol (c +! 1, loopRow (startRow, b)) end in loopCol (startCol, b) @@ -310,8 +310,8 @@ structure Array2 : ARRAY2 = dst, dst_row, dst_col} = let val {startRow, stopRow, startCol, stopCol} = checkRegion src - val nrows = stopRow -? startRow - val ncols = stopCol -? startCol + val nrows = stopRow -! startRow + val ncols = stopCol -! startCol val {startRow = dst_row, startCol = dst_col, ...} = checkRegion' {base = dst, row = dst_row, col = dst_col, nrows = SOME nrows, @@ -330,13 +330,13 @@ structure Array2 : ARRAY2 = if i < start then () else (f i; loop (i - 1)) - in loop (stop -? 1) + in loop (stop -! 1) end val forRows = if startRow <= dst_row then forDown else forUp val forCols = if startCol <= dst_col then forUp else forDown in forRows (0, nrows, fn r => forCols (0, ncols, fn c => - unsafeUpdate' (dst, dst_row +? r, dst_col +? c, - unsafeSub' (base, startRow +? r, startCol +? c)))) + unsafeUpdate' (dst, dst_row +! r, dst_col +! c, + unsafeSub' (base, startRow +! r, startCol +! c)))) end end diff --git a/basis-library/arrays-and-vectors/sequence.fun b/basis-library/arrays-and-vectors/sequence.fun index 9ce7af531d..4340e4e0bb 100644 --- a/basis-library/arrays-and-vectors/sequence.fun +++ b/basis-library/arrays-and-vectors/sequence.fun @@ -68,9 +68,9 @@ structure SeqIndex = functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = struct - val op +? = SeqIndex.+? val op +! = SeqIndex.+! - val op -? = SeqIndex.-? + val op +$ = SeqIndex.+$ + val op -! = SeqIndex.-! val op <= = SeqIndex.<= val op > = SeqIndex.> val op >= = SeqIndex.>= @@ -246,9 +246,9 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = val add = if Primitive.Controls.safe then (fn (x, s) => - (s +! S.Slice.length (toSlice x)) + (s +$ S.Slice.length (toSlice x)) handle Overflow => raise Size) - else (fn (x, s) => s +? S.Slice.length (toSlice x)) + else (fn (x, s) => s +! S.Slice.length (toSlice x)) val n = List.foldl add 0 xs val a = Primitive.Array.alloc n fun loop (di, xs) = @@ -258,7 +258,7 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = let val sl = toSlice x in S.Slice.unsafeCopy {dst = a, di = di, src = sl} - ; loop (di +? S.Slice.length sl, xs) + ; loop (di +! S.Slice.length sl, xs) end in loop (0, xs) @@ -276,10 +276,10 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = val add = if Primitive.Controls.safe then (fn (x, s) => - (s +! sepn +! S.Slice.length (toSlice x)) + (s +$ sepn +$ S.Slice.length (toSlice x)) handle Overflow => raise Size) else (fn (x, s) => - (s +? sepn +? S.Slice.length (toSlice x))) + (s +! sepn +! S.Slice.length (toSlice x))) val n = List.foldl add (S.Slice.length (toSlice x)) xs val a = Primitive.Array.alloc n fun loop (di, xs) = @@ -296,9 +296,9 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = let val sl = toSlice x val _ = S.Slice.unsafeCopy {dst = a, di = di, src = sl} - val di = di +? S.Slice.length sl + val di = di +! S.Slice.length sl val _ = S.Slice.unsafeCopy {dst = a, di = di, src = sep} - val di = di +? sepn + val di = di +! sepn in loop (di, xs) end @@ -318,7 +318,7 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = in if SeqIndex.> (k, len) then S.Slice.unsafeSubslice (sl, len, SOME 0) - else S.Slice.unsafeSubslice (sl, k, SOME (len -? k)) + else S.Slice.unsafeSubslice (sl, k, SOME (len -! k)) end handle Overflow => (* k is positive, so behavior is specified! *) S.Slice.unsafeSubslice (sl, S.Slice.length sl, SOME 0) @@ -334,7 +334,7 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = in if SeqIndex.> (k, len) then S.Slice.unsafeSubslice (sl, 0, SOME 0) - else S.Slice.unsafeSubslice (sl, 0, SOME (len -? k)) + else S.Slice.unsafeSubslice (sl, 0, SOME (len -! k)) end handle Overflow => (* k is positive, so behavior is specified! *) S.Slice.unsafeSubslice (sl, 0, SOME 0) @@ -347,16 +347,16 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = in if n <= n' then let - val n'' = n' -? n + val n'' = n' -! n fun loop (i, j) = if i > n'' then false else if j >= n then true else if eq (S.unsafeSub (seq, j), - S.Slice.unsafeSub (sl, i +? j)) - then loop (i, j +? 1) - else loop (i +? 1, 0) + S.Slice.unsafeSub (sl, i +! j)) + then loop (i, j +! 1) + else loop (i +! 1, 0) in loop (0, 0) end @@ -376,7 +376,7 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = then true else if eq (S.unsafeSub (seq, j), S.Slice.unsafeSub (sl, j)) - then loop (j +? 1) + then loop (j +! 1) else false in loop (0) @@ -392,13 +392,13 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = in if n <= n' then let - val n'' = n' -? n + val n'' = n' -! n fun loop (j) = if j >= n then true else if eq (S.unsafeSub (seq, j), - S.Slice.unsafeSub (sl, n'' +? j)) - then loop (j +? 1) + S.Slice.unsafeSub (sl, n'' +! j)) + then loop (j +! 1) else false in loop (0) @@ -423,14 +423,14 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = fun make finish p sl = let val (seq, start, len) = S.Slice.base sl - val max = start +? len + val max = start +! len fun loop (i, start, sls) = if i >= max then List.rev (finish (seq, start, i, sls)) else if p (S.unsafeSub (seq, i)) - then loop (i +? 1, i +? 1, finish (seq, start, i, sls)) - else loop (i +? 1, start, sls) + then loop (i +! 1, i +! 1, finish (seq, start, i, sls)) + else loop (i +! 1, start, sls) in loop (start, start, []) end in @@ -441,14 +441,14 @@ functor Sequence (S: PRIM_SEQUENCE): SEQUENCE = else (fromSlice (S.Slice.unsafeSlice - (seq, start, SOME (stop -? start)))) + (seq, start, SOME (stop -! start)))) :: sls) p sl fun fieldsGen fromSlice p sl = make (fn (seq, start, stop, sls) => (fromSlice (S.Slice.unsafeSlice - (seq, start, SOME (stop -? start)))) + (seq, start, SOME (stop -! start)))) :: sls) p sl end diff --git a/basis-library/arrays-and-vectors/sequence0.sml b/basis-library/arrays-and-vectors/sequence0.sml index e5f01dc200..b5de282628 100644 --- a/basis-library/arrays-and-vectors/sequence0.sml +++ b/basis-library/arrays-and-vectors/sequence0.sml @@ -27,9 +27,9 @@ functor PrimSequence (S: sig struct structure Array = Primitive.Array - val op +? = SeqIndex.+? + val op +! = SeqIndex.+! val op + = SeqIndex.+ - val op -? = SeqIndex.-? + val op -! = SeqIndex.-! val op < = SeqIndex.< val op <= = SeqIndex.<= val op > = SeqIndex.> @@ -130,7 +130,7 @@ functor PrimSequence (S: sig val (x, b) = f (i, b) val () = Array.updateUnsafe (a, i, x) in - loop (i +? 1, b) + loop (i +! 1, b) end val b = loop (0, b) in @@ -154,13 +154,13 @@ functor PrimSequence (S: sig fun length (T {len, ...}) = len fun unsafeSub (T {seq, start, ...}, i) = - S.subUnsafe (seq, start +? i) + S.subUnsafe (seq, start +! i) fun sub (sl as T {len, ...}, i) = if Primitive.Controls.safe andalso geu (i, len) then raise Subscript else unsafeSub (sl, i) fun unsafeUpdate (T {seq, start, ...}, i, x) = - S.updateUnsafe (seq, start +? i, x) + S.updateUnsafe (seq, start +! i, x) fun update (sl as T {len, ...}, i, x) = if Primitive.Controls.safe andalso geu (i, len) then raise Subscript @@ -168,7 +168,7 @@ functor PrimSequence (S: sig fun uninitIsNop (T {seq, ...}) = S.uninitIsNop seq fun unsafeUninit (T {seq, start, ...}, i) = - S.uninitUnsafe (seq, start +? i) + S.uninitUnsafe (seq, start +! i) fun uninit (sl as T {len, ...}, i) = if Primitive.Controls.safe andalso geu (i, len) then raise Subscript @@ -179,15 +179,15 @@ functor PrimSequence (S: sig len: SeqIndex.int, overlap: unit -> bool} = let - fun move i = Array.updateUnsafe (dst, di +? i, S.subUnsafe (src, si +? i)) - val len = len -? 1 + fun move i = Array.updateUnsafe (dst, di +! i, S.subUnsafe (src, si +! i)) + val len = len -! 1 in if overlap () then let fun loop i = if i < 0 then () - else (move i; loop (i -? 1)) + else (move i; loop (i -! 1)) in loop len end @@ -195,7 +195,7 @@ functor PrimSequence (S: sig fun loop i = if i > len then () - else (move i; loop (i +? 1)) + else (move i; loop (i +! 1)) in loop 0 end @@ -222,13 +222,13 @@ functor PrimSequence (S: sig src = T {seq = src, start = si, len}} = if Primitive.Controls.safe andalso (gtu (di, Array.length dst) - orelse gtu (di +? len, Array.length dst)) + orelse gtu (di +! len, Array.length dst)) then raise Subscript else let fun overlap () = S.sameArray (dst, src) andalso si < di - andalso di <= si +? len + andalso di <= si +! len in maybeSmallCopy {dst = dst, di = di, src = src, si = si, @@ -240,9 +240,9 @@ functor PrimSequence (S: sig T {seq = seq, start = 0, len = S.length seq} fun unsafeSubslice (T {seq, start, len}, start', len') = T {seq = seq, - start = start +? start', + start = start +! start', len = (case len' of - NONE => len -? start' + NONE => len -! start' | SOME len' => len')} fun unsafeSlice (seq, start, len) = unsafeSubslice (full seq, start, len) @@ -253,15 +253,15 @@ functor PrimSequence (S: sig andalso gtu (start', len) then raise Subscript else T {seq = seq, - start = start +? start', - len = len -? start'} + start = start +! start', + len = len -! start'} | SOME len' => if Primitive.Controls.safe andalso (gtu (start', len) - orelse gtu (len', len -? start')) + orelse gtu (len', len -! start')) then raise Subscript else T {seq = seq, - start = start +? start', + start = start +! start', len = len'} fun slice (seq: 'a sequence, start, len) = subslice (full seq, start, len) @@ -273,26 +273,26 @@ functor PrimSequence (S: sig then NONE else SOME (S.subUnsafe (seq, start), T {seq = seq, - start = start +? 1, - len = len -? 1}) + start = start +! 1, + len = len -! 1}) fun foldli f b (T {seq, start, len}) = let val min = start - val len = len -? 1 - val max = start +? len + val len = len -! 1 + val max = start +! len fun loop (i, b) = if i > max then b - else loop (i +? 1, f (i -? min, S.subUnsafe (seq, i), b)) + else loop (i +! 1, f (i -! min, S.subUnsafe (seq, i), b)) in loop (min, b) end fun foldri f b (T {seq, start, len}) = let val min = start - val len = len -? 1 - val max = start +? len + val len = len -! 1 + val max = start +! len fun loop (i, b) = if i < min then b - else loop (i -? 1, f (i -? min, S.subUnsafe (seq, i), b)) + else loop (i -! 1, f (i -! min, S.subUnsafe (seq, i), b)) in loop (max, b) end local @@ -304,20 +304,20 @@ functor PrimSequence (S: sig fun appi f sl = foldli (fn (i, x, ()) => f (i, x)) () sl fun app f sl = appi (f o #2) sl fun mapi f (T {seq, start, len}) = - tabulate (len, fn i => f (i, S.subUnsafe (seq, start +? i))) + tabulate (len, fn i => f (i, S.subUnsafe (seq, start +! i))) fun map f sl = mapi (f o #2) sl fun findi p (T {seq, start, len}) = let val min = start - val len = len -? 1 - val max = start +? len + val len = len -! 1 + val max = start +! len fun loop i = if i > max then NONE - else let val z = (i -? min, S.subUnsafe (seq, i)) + else let val z = (i -! min, S.subUnsafe (seq, i)) in if p z then SOME z - else loop (i +? 1) + else loop (i +! 1) end in loop min end @@ -337,8 +337,8 @@ functor PrimSequence (S: sig let val min1 = start1 val min2 = start2 - val max1 = start1 +? len1 - val max2 = start2 +? len2 + val max1 = start1 +! len1 + val max2 = start2 +! len2 fun loop (i, j) = case (i >= max1, j >= max2) of (true, true) => EQUAL @@ -347,7 +347,7 @@ functor PrimSequence (S: sig | (false, false) => (case cmp (S.subUnsafe (seq1, i), S.subUnsafe (seq2, j)) of - EQUAL => loop (i +? 1, j +? 1) + EQUAL => loop (i +! 1, j +! 1) | ans => ans) in loop (min1, min2) end @@ -369,7 +369,7 @@ functor PrimSequence (S: sig let val (seq1, start1, len1) = base sl1 val (seq2, start2, len2) = base sl2 - val n = len1 +? len2 + val n = len1 +! len2 val a = arrayAlloc n in S.copyUnsafe (a, 0, seq1, start1, len1) @@ -377,16 +377,16 @@ functor PrimSequence (S: sig ; S.fromArray a end fun split (T {seq, start, len}, i) = - (unsafeSlice (seq, start, SOME (i -? start)), - unsafeSlice (seq, i, SOME (len -? (i -? start)))) + (unsafeSlice (seq, start, SOME (i -! start)), + unsafeSlice (seq, i, SOME (len -! (i -! start)))) fun splitl f (sl as T {seq, start, len}) = let - val stop = start +? len + val stop = start +! len fun loop i = if i >= stop then i else if f (S.subUnsafe (seq, i)) - then loop (i +? 1) + then loop (i +! 1) else i in split (sl, loop start) end @@ -396,15 +396,15 @@ functor PrimSequence (S: sig if i < start then start else if f (S.subUnsafe (seq, i)) - then loop (i -? 1) - else i +? 1 - in split (sl, loop (start +? len -? 1)) + then loop (i -! 1) + else i +! 1 + in split (sl, loop (start +! len -! 1)) end fun splitAt (T {seq, start, len}, i) = if Primitive.Controls.safe andalso gtu (i, len) then raise Subscript else (unsafeSlice (seq, start, SOME i), - unsafeSlice (seq, start +? i, SOME (len -? i))) + unsafeSlice (seq, start +! i, SOME (len -! i))) fun dropl p s = #2 (splitl p s) fun dropr p s = #1 (splitr p s) fun takel p s = #1 (splitl p s) @@ -414,19 +414,19 @@ functor PrimSequence (S: sig (sl as T {seq, start, len}) = let val len' = S.length seq' - val max = start +? len -? len' +? 1 + val max = start +! len -! len' +! 1 (* loop returns the index of the front of the suffix. *) fun loop i = if i >= max - then start +? len + then start +! len else let fun loop' j = if j >= len' then i - else if eq (S.subUnsafe (seq, i +? j), + else if eq (S.subUnsafe (seq, i +! j), S.subUnsafe (seq', j)) - then loop' (j +? 1) - else loop (i +? 1) + then loop' (j +! 1) + else loop (i +! 1) in loop' 0 end in split (sl, loop start) @@ -435,9 +435,9 @@ functor PrimSequence (S: sig (T {seq, start, ...}, T {seq = seq', start = start', len = len'}) = if Primitive.Controls.safe andalso - (not (eq (seq, seq')) orelse start' +? len' < start) + (not (eq (seq, seq')) orelse start' +! len' < start) then raise Span - else unsafeSlice (seq, start, SOME ((start' +? len') -? start)) + else unsafeSlice (seq, start, SOME ((start' +! len') -! start)) end local diff --git a/basis-library/integer/int-inf.sig b/basis-library/integer/int-inf.sig index 6574491516..c2f9149c80 100644 --- a/basis-library/integer/int-inf.sig +++ b/basis-library/integer/int-inf.sig @@ -34,10 +34,10 @@ signature INT_INF_EXTRA = val zero: int val one: int - val +? : int * int -> int - val *? : int * int -> int - val -? : int * int -> int - val ~? : int -> int + val +! : int * int -> int + val *! : int * int -> int + val -! : int * int -> int + val ~! : int -> int val ltu: int * int -> bool val leu: int * int -> bool diff --git a/basis-library/integer/int-inf0.sml b/basis-library/integer/int-inf0.sml index ec6772392b..fac4bc7af1 100644 --- a/basis-library/integer/int-inf0.sml +++ b/basis-library/integer/int-inf0.sml @@ -32,23 +32,19 @@ signature PRIM_INT_INF = val abs: int -> int val +! : int * int -> int - val +? : int * int -> int val + : int * int -> int val divMod: int * int -> int * int val div: int * int -> int val gcd: int * int -> int val mod: int * int -> int val *! : int * int -> int - val *? : int * int -> int val * : int * int -> int val ~! : int -> int - val ~? : int -> int val ~ : int -> int val quotRem: int * int -> int * int val quot: int * int -> int val rem: int * int -> int val -! : int * int -> int - val -? : int * int -> int val - : int * int -> int val < : int * int -> bool @@ -1015,9 +1011,9 @@ structure IntInf = | SOME i => i end in - val bigAdd = make (I.+!, Prim.+, S.max, 1) - val bigSub = make (I.-!, Prim.-, S.max, 1) - val bigMul = make (I.*!, Prim.*, S.+, 0) + val bigAdd = make (I.+$, Prim.+, S.max, 1) + val bigSub = make (I.-$, Prim.-, S.max, 1) + val bigMul = make (I.*$, Prim.*, S.+, 0) end fun bigNeg (arg: bigInt): bigInt = @@ -1325,23 +1321,19 @@ structure IntInf = val abs = bigAbs val op +! = bigAdd - val op +? = bigAdd val op + = bigAdd val divMod = bigDivMod val op div = bigDiv val gcd = bigGcd val op mod = bigMod val op *! = bigMul - val op *? = bigMul val op * = bigMul val op ~! = bigNeg - val op ~? = bigNeg val op ~ = bigNeg val quotRem = bigQuotRem val quot = bigQuot val rem = bigRem val op -! = bigSub - val op -? = bigSub val op - = bigSub val op < = bigLT diff --git a/basis-library/integer/int.sml b/basis-library/integer/int.sml index 135e83db89..6b833a4643 100644 --- a/basis-library/integer/int.sml +++ b/basis-library/integer/int.sml @@ -80,7 +80,7 @@ in let val _ = CharArray.update - (buf, i, StringCvt.digitToChar (toInt (~? (rem (q, radix))))) + (buf, i, StringCvt.digitToChar (toInt (~! (rem (q, radix))))) val q = quot (q, radix) in if q = zero @@ -103,7 +103,7 @@ in else loop (q, Int.- (i, 1)) end in - loop (if n < zero then n else ~? n, Int.- (maxNumDigits, 1)) + loop (if n < zero then n else ~! n, Int.- (maxNumDigits, 1)) end) end @@ -138,15 +138,15 @@ fun scan radix reader s = | SOME (c, s') => case charToDigit c of NONE => SOME (zero, s) - | SOME n => finishNum (s', ~? n) + | SOME n => finishNum (s', ~! n) else case charToDigit c of NONE => SOME (zero, s) - | SOME n => finishNum (s', ~? n)) + | SOME n => finishNum (s', ~! n)) | (SOME (c, s), _) => case charToDigit c of NONE => NONE - | SOME n => finishNum (s, ~? n) + | SOME n => finishNum (s, ~! n) fun negate s = case num s of NONE => NONE diff --git a/basis-library/integer/integer.sig b/basis-library/integer/integer.sig index 4fe4c1aee5..4f2ed217db 100644 --- a/basis-library/integer/integer.sig +++ b/basis-library/integer/integer.sig @@ -58,10 +58,10 @@ signature INTEGER_EXTRA = val maxInt' : int val minInt' : int - val +? : int * int -> int - val *? : int * int -> int - val -? : int * int -> int - val ~? : int -> int + val +! : int * int -> int + val *! : int * int -> int + val -! : int * int -> int + val ~! : int -> int val andb: int * int -> int val << : int * Word.word -> int diff --git a/basis-library/integer/num0.sml b/basis-library/integer/num0.sml index 72f3c98b33..bab330379d 100644 --- a/basis-library/integer/num0.sml +++ b/basis-library/integer/num0.sml @@ -187,7 +187,7 @@ functor MkNum0 (S: MKNUM0_ARG): sig else if y < zero then if x = zero then zero - else quotUnsafe (x -? one, y) -? one + else quotUnsafe (x -! one, y) -! one else raise Div else if y < zero then if (Primitive.Controls.detectOverflow @@ -198,7 +198,7 @@ functor MkNum0 (S: MKNUM0_ARG): sig else minInt' else quotUnsafe (x, y) else if y > zero - then quotUnsafe (x +? one, y) -? one + then quotUnsafe (x +! one, y) -! one else raise Div fun x mod y = @@ -208,14 +208,14 @@ functor MkNum0 (S: MKNUM0_ARG): sig else if y < zero then if x = zero then zero - else remUnsafe (x -? one, y) +? (y + one) + else remUnsafe (x -! one, y) +! (y + one) else raise Div else if y < zero then if x = minInt' andalso y = ~one then zero else remUnsafe (x, y) else if y > zero - then remUnsafe (x +? one, y) +? (y -? one) + then remUnsafe (x +! one, y) +! (y -! one) else raise Div local diff --git a/basis-library/list/list.sml b/basis-library/list/list.sml index 57cbe88696..1a86acbfca 100644 --- a/basis-library/list/list.sml +++ b/basis-library/list/list.sml @@ -44,7 +44,7 @@ structure List: LIST = in loop (l, b) end - fun length l = foldl (fn (_, n) => n +? 1) 0 l + fun length l = foldl (fn (_, n) => n +! 1) 0 l fun appendRev (l1, l2) = foldl (op ::) l2 l1 diff --git a/basis-library/primitive/basis-ffi.sml b/basis-library/primitive/basis-ffi.sml index 53a3b4413a..47e017bfe0 100644 --- a/basis-library/primitive/basis-ffi.sml +++ b/basis-library/primitive/basis-ffi.sml @@ -1148,6 +1148,7 @@ val andb = _import "Word16_andb" private : Word16.t * Word16.t -> Word16.t; val equal = _import "Word16_equal" private : Word16.t * Word16.t -> Bool.t; val lshift = _import "Word16_lshift" private : Word16.t * Word32.t -> Word16.t; val neg = _import "Word16_neg" private : Word16.t -> Word16.t; +val negCheckP = _import "Word16_negCheckP" private : Int16.t -> Bool.t; val notb = _import "Word16_notb" private : Word16.t -> Word16.t; val orb = _import "Word16_orb" private : Word16.t * Word16.t -> Word16.t; val rol = _import "Word16_rol" private : Word16.t * Word32.t -> Word16.t; @@ -1164,6 +1165,7 @@ val castToReal32 = _import "Word32_castToReal32" private : Word32.t -> Real32.t; val equal = _import "Word32_equal" private : Word32.t * Word32.t -> Bool.t; val lshift = _import "Word32_lshift" private : Word32.t * Word32.t -> Word32.t; val neg = _import "Word32_neg" private : Word32.t -> Word32.t; +val negCheckP = _import "Word32_negCheckP" private : Int32.t -> Bool.t; val notb = _import "Word32_notb" private : Word32.t -> Word32.t; val orb = _import "Word32_orb" private : Word32.t * Word32.t -> Word32.t; val rol = _import "Word32_rol" private : Word32.t * Word32.t -> Word32.t; @@ -1182,6 +1184,7 @@ val fetch = _import "Word64_fetch" private : (Word64.t) ref -> Word64.t; val lshift = _import "Word64_lshift" private : Word64.t * Word32.t -> Word64.t; val move = _import "Word64_move" private : (Word64.t) ref * (Word64.t) ref -> unit; val neg = _import "Word64_neg" private : Word64.t -> Word64.t; +val negCheckP = _import "Word64_negCheckP" private : Int64.t -> Bool.t; val notb = _import "Word64_notb" private : Word64.t -> Word64.t; val orb = _import "Word64_orb" private : Word64.t * Word64.t -> Word64.t; val rol = _import "Word64_rol" private : Word64.t * Word32.t -> Word64.t; @@ -1198,6 +1201,7 @@ val andb = _import "Word8_andb" private : Word8.t * Word8.t -> Word8.t; val equal = _import "Word8_equal" private : Word8.t * Word8.t -> Bool.t; val lshift = _import "Word8_lshift" private : Word8.t * Word32.t -> Word8.t; val neg = _import "Word8_neg" private : Word8.t -> Word8.t; +val negCheckP = _import "Word8_negCheckP" private : Int8.t -> Bool.t; val notb = _import "Word8_notb" private : Word8.t -> Word8.t; val orb = _import "Word8_orb" private : Word8.t * Word8.t -> Word8.t; val rol = _import "Word8_rol" private : Word8.t * Word32.t -> Word8.t; @@ -1207,7 +1211,7 @@ val xorb = _import "Word8_xorb" private : Word8.t * Word8.t -> Word8.t; end structure WordS16 = struct -val addCheckOverflows = _import "WordS16_addCheckOverflows" private : Int16.t * Int16.t -> Bool.t; +val addCheckP = _import "WordS16_addCheckP" private : Int16.t * Int16.t -> Bool.t; val extdToWord16 = _import "WordS16_extdToWord16" private : Int16.t -> Word16.t; val extdToWord32 = _import "WordS16_extdToWord32" private : Int16.t -> Word32.t; val extdToWord64 = _import "WordS16_extdToWord64" private : Int16.t -> Word64.t; @@ -1217,18 +1221,17 @@ val gt = _import "WordS16_gt" private : Int16.t * Int16.t -> Bool.t; val le = _import "WordS16_le" private : Int16.t * Int16.t -> Bool.t; val lt = _import "WordS16_lt" private : Int16.t * Int16.t -> Bool.t; val mul = _import "WordS16_mul" private : Int16.t * Int16.t -> Int16.t; -val mulCheckOverflows = _import "WordS16_mulCheckOverflows" private : Int16.t * Int16.t -> Bool.t; -val negCheckOverflows = _import "WordS16_negCheckOverflows" private : Int16.t -> Bool.t; +val mulCheckP = _import "WordS16_mulCheckP" private : Int16.t * Int16.t -> Bool.t; val quot = _import "WordS16_quot" private : Int16.t * Int16.t -> Int16.t; val rem = _import "WordS16_rem" private : Int16.t * Int16.t -> Int16.t; val rndToReal32 = _import "WordS16_rndToReal32" private : Int16.t -> Real32.t; val rndToReal64 = _import "WordS16_rndToReal64" private : Int16.t -> Real64.t; val rshift = _import "WordS16_rshift" private : Int16.t * Word32.t -> Int16.t; -val subCheckOverflows = _import "WordS16_subCheckOverflows" private : Int16.t * Int16.t -> Bool.t; +val subCheckP = _import "WordS16_subCheckP" private : Int16.t * Int16.t -> Bool.t; end structure WordS32 = struct -val addCheckOverflows = _import "WordS32_addCheckOverflows" private : Int32.t * Int32.t -> Bool.t; +val addCheckP = _import "WordS32_addCheckP" private : Int32.t * Int32.t -> Bool.t; val extdToWord16 = _import "WordS32_extdToWord16" private : Int32.t -> Word16.t; val extdToWord32 = _import "WordS32_extdToWord32" private : Int32.t -> Word32.t; val extdToWord64 = _import "WordS32_extdToWord64" private : Int32.t -> Word64.t; @@ -1238,18 +1241,17 @@ val gt = _import "WordS32_gt" private : Int32.t * Int32.t -> Bool.t; val le = _import "WordS32_le" private : Int32.t * Int32.t -> Bool.t; val lt = _import "WordS32_lt" private : Int32.t * Int32.t -> Bool.t; val mul = _import "WordS32_mul" private : Int32.t * Int32.t -> Int32.t; -val mulCheckOverflows = _import "WordS32_mulCheckOverflows" private : Int32.t * Int32.t -> Bool.t; -val negCheckOverflows = _import "WordS32_negCheckOverflows" private : Int32.t -> Bool.t; +val mulCheckP = _import "WordS32_mulCheckP" private : Int32.t * Int32.t -> Bool.t; val quot = _import "WordS32_quot" private : Int32.t * Int32.t -> Int32.t; val rem = _import "WordS32_rem" private : Int32.t * Int32.t -> Int32.t; val rndToReal32 = _import "WordS32_rndToReal32" private : Int32.t -> Real32.t; val rndToReal64 = _import "WordS32_rndToReal64" private : Int32.t -> Real64.t; val rshift = _import "WordS32_rshift" private : Int32.t * Word32.t -> Int32.t; -val subCheckOverflows = _import "WordS32_subCheckOverflows" private : Int32.t * Int32.t -> Bool.t; +val subCheckP = _import "WordS32_subCheckP" private : Int32.t * Int32.t -> Bool.t; end structure WordS64 = struct -val addCheckOverflows = _import "WordS64_addCheckOverflows" private : Int64.t * Int64.t -> Bool.t; +val addCheckP = _import "WordS64_addCheckP" private : Int64.t * Int64.t -> Bool.t; val extdToWord16 = _import "WordS64_extdToWord16" private : Int64.t -> Word16.t; val extdToWord32 = _import "WordS64_extdToWord32" private : Int64.t -> Word32.t; val extdToWord64 = _import "WordS64_extdToWord64" private : Int64.t -> Word64.t; @@ -1259,18 +1261,17 @@ val gt = _import "WordS64_gt" private : Int64.t * Int64.t -> Bool.t; val le = _import "WordS64_le" private : Int64.t * Int64.t -> Bool.t; val lt = _import "WordS64_lt" private : Int64.t * Int64.t -> Bool.t; val mul = _import "WordS64_mul" private : Int64.t * Int64.t -> Int64.t; -val mulCheckOverflows = _import "WordS64_mulCheckOverflows" private : Int64.t * Int64.t -> Bool.t; -val negCheckOverflows = _import "WordS64_negCheckOverflows" private : Int64.t -> Bool.t; +val mulCheckP = _import "WordS64_mulCheckP" private : Int64.t * Int64.t -> Bool.t; val quot = _import "WordS64_quot" private : Int64.t * Int64.t -> Int64.t; val rem = _import "WordS64_rem" private : Int64.t * Int64.t -> Int64.t; val rndToReal32 = _import "WordS64_rndToReal32" private : Int64.t -> Real32.t; val rndToReal64 = _import "WordS64_rndToReal64" private : Int64.t -> Real64.t; val rshift = _import "WordS64_rshift" private : Int64.t * Word32.t -> Int64.t; -val subCheckOverflows = _import "WordS64_subCheckOverflows" private : Int64.t * Int64.t -> Bool.t; +val subCheckP = _import "WordS64_subCheckP" private : Int64.t * Int64.t -> Bool.t; end structure WordS8 = struct -val addCheckOverflows = _import "WordS8_addCheckOverflows" private : Int8.t * Int8.t -> Bool.t; +val addCheckP = _import "WordS8_addCheckP" private : Int8.t * Int8.t -> Bool.t; val extdToWord16 = _import "WordS8_extdToWord16" private : Int8.t -> Word16.t; val extdToWord32 = _import "WordS8_extdToWord32" private : Int8.t -> Word32.t; val extdToWord64 = _import "WordS8_extdToWord64" private : Int8.t -> Word64.t; @@ -1280,18 +1281,17 @@ val gt = _import "WordS8_gt" private : Int8.t * Int8.t -> Bool.t; val le = _import "WordS8_le" private : Int8.t * Int8.t -> Bool.t; val lt = _import "WordS8_lt" private : Int8.t * Int8.t -> Bool.t; val mul = _import "WordS8_mul" private : Int8.t * Int8.t -> Int8.t; -val mulCheckOverflows = _import "WordS8_mulCheckOverflows" private : Int8.t * Int8.t -> Bool.t; -val negCheckOverflows = _import "WordS8_negCheckOverflows" private : Int8.t -> Bool.t; +val mulCheckP = _import "WordS8_mulCheckP" private : Int8.t * Int8.t -> Bool.t; val quot = _import "WordS8_quot" private : Int8.t * Int8.t -> Int8.t; val rem = _import "WordS8_rem" private : Int8.t * Int8.t -> Int8.t; val rndToReal32 = _import "WordS8_rndToReal32" private : Int8.t -> Real32.t; val rndToReal64 = _import "WordS8_rndToReal64" private : Int8.t -> Real64.t; val rshift = _import "WordS8_rshift" private : Int8.t * Word32.t -> Int8.t; -val subCheckOverflows = _import "WordS8_subCheckOverflows" private : Int8.t * Int8.t -> Bool.t; +val subCheckP = _import "WordS8_subCheckP" private : Int8.t * Int8.t -> Bool.t; end structure WordU16 = struct -val addCheckOverflows = _import "WordU16_addCheckOverflows" private : Word16.t * Word16.t -> Bool.t; +val addCheckP = _import "WordU16_addCheckP" private : Word16.t * Word16.t -> Bool.t; val extdToWord16 = _import "WordU16_extdToWord16" private : Word16.t -> Word16.t; val extdToWord32 = _import "WordU16_extdToWord32" private : Word16.t -> Word32.t; val extdToWord64 = _import "WordU16_extdToWord64" private : Word16.t -> Word64.t; @@ -1301,7 +1301,7 @@ val gt = _import "WordU16_gt" private : Word16.t * Word16.t -> Bool.t; val le = _import "WordU16_le" private : Word16.t * Word16.t -> Bool.t; val lt = _import "WordU16_lt" private : Word16.t * Word16.t -> Bool.t; val mul = _import "WordU16_mul" private : Word16.t * Word16.t -> Word16.t; -val mulCheckOverflows = _import "WordU16_mulCheckOverflows" private : Word16.t * Word16.t -> Bool.t; +val mulCheckP = _import "WordU16_mulCheckP" private : Word16.t * Word16.t -> Bool.t; val quot = _import "WordU16_quot" private : Word16.t * Word16.t -> Word16.t; val rem = _import "WordU16_rem" private : Word16.t * Word16.t -> Word16.t; val rndToReal32 = _import "WordU16_rndToReal32" private : Word16.t -> Real32.t; @@ -1310,7 +1310,7 @@ val rshift = _import "WordU16_rshift" private : Word16.t * Word32.t -> Word16.t; end structure WordU32 = struct -val addCheckOverflows = _import "WordU32_addCheckOverflows" private : Word32.t * Word32.t -> Bool.t; +val addCheckP = _import "WordU32_addCheckP" private : Word32.t * Word32.t -> Bool.t; val extdToWord16 = _import "WordU32_extdToWord16" private : Word32.t -> Word16.t; val extdToWord32 = _import "WordU32_extdToWord32" private : Word32.t -> Word32.t; val extdToWord64 = _import "WordU32_extdToWord64" private : Word32.t -> Word64.t; @@ -1320,7 +1320,7 @@ val gt = _import "WordU32_gt" private : Word32.t * Word32.t -> Bool.t; val le = _import "WordU32_le" private : Word32.t * Word32.t -> Bool.t; val lt = _import "WordU32_lt" private : Word32.t * Word32.t -> Bool.t; val mul = _import "WordU32_mul" private : Word32.t * Word32.t -> Word32.t; -val mulCheckOverflows = _import "WordU32_mulCheckOverflows" private : Word32.t * Word32.t -> Bool.t; +val mulCheckP = _import "WordU32_mulCheckP" private : Word32.t * Word32.t -> Bool.t; val quot = _import "WordU32_quot" private : Word32.t * Word32.t -> Word32.t; val rem = _import "WordU32_rem" private : Word32.t * Word32.t -> Word32.t; val rndToReal32 = _import "WordU32_rndToReal32" private : Word32.t -> Real32.t; @@ -1329,7 +1329,7 @@ val rshift = _import "WordU32_rshift" private : Word32.t * Word32.t -> Word32.t; end structure WordU64 = struct -val addCheckOverflows = _import "WordU64_addCheckOverflows" private : Word64.t * Word64.t -> Bool.t; +val addCheckP = _import "WordU64_addCheckP" private : Word64.t * Word64.t -> Bool.t; val extdToWord16 = _import "WordU64_extdToWord16" private : Word64.t -> Word16.t; val extdToWord32 = _import "WordU64_extdToWord32" private : Word64.t -> Word32.t; val extdToWord64 = _import "WordU64_extdToWord64" private : Word64.t -> Word64.t; @@ -1339,7 +1339,7 @@ val gt = _import "WordU64_gt" private : Word64.t * Word64.t -> Bool.t; val le = _import "WordU64_le" private : Word64.t * Word64.t -> Bool.t; val lt = _import "WordU64_lt" private : Word64.t * Word64.t -> Bool.t; val mul = _import "WordU64_mul" private : Word64.t * Word64.t -> Word64.t; -val mulCheckOverflows = _import "WordU64_mulCheckOverflows" private : Word64.t * Word64.t -> Bool.t; +val mulCheckP = _import "WordU64_mulCheckP" private : Word64.t * Word64.t -> Bool.t; val quot = _import "WordU64_quot" private : Word64.t * Word64.t -> Word64.t; val rem = _import "WordU64_rem" private : Word64.t * Word64.t -> Word64.t; val rndToReal32 = _import "WordU64_rndToReal32" private : Word64.t -> Real32.t; @@ -1348,7 +1348,7 @@ val rshift = _import "WordU64_rshift" private : Word64.t * Word32.t -> Word64.t; end structure WordU8 = struct -val addCheckOverflows = _import "WordU8_addCheckOverflows" private : Word8.t * Word8.t -> Bool.t; +val addCheckP = _import "WordU8_addCheckP" private : Word8.t * Word8.t -> Bool.t; val extdToWord16 = _import "WordU8_extdToWord16" private : Word8.t -> Word16.t; val extdToWord32 = _import "WordU8_extdToWord32" private : Word8.t -> Word32.t; val extdToWord64 = _import "WordU8_extdToWord64" private : Word8.t -> Word64.t; @@ -1358,7 +1358,7 @@ val gt = _import "WordU8_gt" private : Word8.t * Word8.t -> Bool.t; val le = _import "WordU8_le" private : Word8.t * Word8.t -> Bool.t; val lt = _import "WordU8_lt" private : Word8.t * Word8.t -> Bool.t; val mul = _import "WordU8_mul" private : Word8.t * Word8.t -> Word8.t; -val mulCheckOverflows = _import "WordU8_mulCheckOverflows" private : Word8.t * Word8.t -> Bool.t; +val mulCheckP = _import "WordU8_mulCheckP" private : Word8.t * Word8.t -> Bool.t; val quot = _import "WordU8_quot" private : Word8.t * Word8.t -> Word8.t; val rem = _import "WordU8_rem" private : Word8.t * Word8.t -> Word8.t; val rndToReal32 = _import "WordU8_rndToReal32" private : Word8.t -> Real32.t; diff --git a/basis-library/primitive/prim-int.sml b/basis-library/primitive/prim-int.sml index dd0ea8705d..f68f00d8da 100644 --- a/basis-library/primitive/prim-int.sml +++ b/basis-library/primitive/prim-int.sml @@ -17,18 +17,22 @@ signature PRIM_INTEGER = val sizeInBitsWord: Primitive.Word32.word val precision: Primitive.Int32.int option + val +? : int * int -> bool val +! : int * int -> int - val +? : int * int -> int + val +$ : int * int -> int val + : int * int -> int - val *! : int * int -> int - val *? : int * int -> int + val *? : int * int -> bool + val *! : int * int -> int + val *$ : int * int -> int val * : int * int -> int + val ~? : int -> bool val ~! : int -> int - val ~? : int -> int + val ~$ : int -> int val ~ : int -> int val quotUnsafe: int * int -> int + val -? : int * int -> bool val -! : int * int -> int - val -? : int * int -> int + val -$ : int * int -> int val - : int * int -> int val remUnsafe: int * int -> int @@ -110,31 +114,40 @@ structure Int8 = IntWordConv.zextdFromInt32ToWord32 sizeInBits val precision = SOME sizeInBits - val +! = Exn.wrapOverflow (_prim "WordS8_addCheck": int * int -> int;) - val +? = _prim "Word8_add": int * int -> int; - val + = - if Controls.detectOverflow - then +! - else +? - val *! = Exn.wrapOverflow (_prim "WordS8_mulCheck": int * int -> int;) - val *? = _prim "WordS8_mul": int * int -> int; - val * = - if Controls.detectOverflow - then *! - else *? - val ~! = Exn.wrapOverflow (_prim "Word8_negCheck": int -> int;) - val ~? = _prim "Word8_neg": int -> int; - val ~ = - if Controls.detectOverflow - then ~! - else ~? + val +? = _prim "WordS8_addCheckP": int * int -> bool; + val +! = _prim "Word8_add": int * int -> int; + val +$ = if Controls.newOverflow then + Exn.mkOverflow (+!, +?) + else + Exn.wrapOverflow (_prim "WordS8_addCheck": int * int -> int;) + val + = if Controls.detectOverflow then +$ else +! + + val *? = _prim "WordS8_mulCheckP": int * int -> bool; + val *! = _prim "WordS8_mul": int * int -> int; + val *$ = if Controls.newOverflow then + Exn.mkOverflow ( *!, *? ) + else + Exn.wrapOverflow (_prim "WordS8_mulCheck": int * int -> int;) + val * = if Controls.detectOverflow then *$ else *! + + val ~? = _prim "Word8_negCheckP": int -> bool; + val ~! = _prim "Word8_neg": int -> int; + val ~$ = if Controls.newOverflow then + Exn.mkOverflow (~!, ~?) + else + Exn.wrapOverflow (_prim "Word8_negCheck": int -> int;) + val ~ = if Controls.detectOverflow then ~$ else ~! + val quotUnsafe = _prim "WordS8_quot": int * int -> int; - val -! = Exn.wrapOverflow (_prim "WordS8_subCheck": int * int -> int;) - val -? = _prim "Word8_sub": int * int -> int; - val - = - if Controls.detectOverflow - then -! - else -? + + val -? = _prim "WordS8_subCheckP": int * int -> bool; + val -! = _prim "Word8_sub": int * int -> int; + val -$ = if Controls.newOverflow then + Exn.mkOverflow (-!, -?) + else + Exn.wrapOverflow (_prim "WordS8_subCheck": int * int -> int;) + val - = if Controls.detectOverflow then -$ else -! + val remUnsafe = _prim "WordS8_rem": int * int -> int; val < = _prim "WordS8_lt": int * int -> bool; @@ -213,31 +226,40 @@ structure Int16 = IntWordConv.zextdFromInt32ToWord32 sizeInBits val precision = SOME sizeInBits - val +! = Exn.wrapOverflow (_prim "WordS16_addCheck": int * int -> int;) - val +? = _prim "Word16_add": int * int -> int; - val + = - if Controls.detectOverflow - then +! - else +? - val *! = Exn.wrapOverflow (_prim "WordS16_mulCheck": int * int -> int;) - val *? = _prim "WordS16_mul": int * int -> int; - val * = - if Controls.detectOverflow - then *! - else *? - val ~! = Exn.wrapOverflow (_prim "Word16_negCheck": int -> int;) - val ~? = _prim "Word16_neg": int -> int; - val ~ = - if Controls.detectOverflow - then ~! - else ~? + val +? = _prim "WordS16_addCheckP": int * int -> bool; + val +! = _prim "Word16_add": int * int -> int; + val +$ = if Controls.newOverflow then + Exn.mkOverflow (+!, +?) + else + Exn.wrapOverflow (_prim "WordS16_addCheck": int * int -> int;) + val + = if Controls.detectOverflow then +$ else +! + + val *? = _prim "WordS16_mulCheckP": int * int -> bool; + val *! = _prim "WordS16_mul": int * int -> int; + val *$ = if Controls.newOverflow then + Exn.mkOverflow ( *!, *? ) + else + Exn.wrapOverflow (_prim "WordS16_mulCheck": int * int -> int;) + val * = if Controls.detectOverflow then *$ else *! + + val ~? = _prim "Word16_negCheckP": int -> bool; + val ~! = _prim "Word16_neg": int -> int; + val ~$ = if Controls.newOverflow then + Exn.mkOverflow (~!, ~?) + else + Exn.wrapOverflow (_prim "Word16_negCheck": int -> int;) + val ~ = if Controls.detectOverflow then ~$ else ~! + val quotUnsafe = _prim "WordS16_quot": int * int -> int; - val -! = Exn.wrapOverflow (_prim "WordS16_subCheck": int * int -> int;) - val -? = _prim "Word16_sub": int * int -> int; - val - = - if Controls.detectOverflow - then -! - else -? + + val -? = _prim "WordS16_subCheckP": int * int -> bool; + val -! = _prim "Word16_sub": int * int -> int; + val -$ = if Controls.newOverflow then + Exn.mkOverflow (-!, -?) + else + Exn.wrapOverflow (_prim "WordS16_subCheck": int * int -> int;) + val - = if Controls.detectOverflow then -$ else -! + val remUnsafe = _prim "WordS16_rem": int * int -> int; val < = _prim "WordS16_lt": int * int -> bool; @@ -380,31 +402,40 @@ structure Int32 = IntWordConv.zextdFromInt32ToWord32 sizeInBits val precision = SOME sizeInBits - val +! = Exn.wrapOverflow (_prim "WordS32_addCheck": int * int -> int;) - val +? = _prim "Word32_add": int * int -> int; - val + = - if Controls.detectOverflow - then +! - else +? - val *! = Exn.wrapOverflow (_prim "WordS32_mulCheck": int * int -> int;) - val *? = _prim "WordS32_mul": int * int -> int; - val * = - if Controls.detectOverflow - then *! - else *? - val ~! = Exn.wrapOverflow (_prim "Word32_negCheck": int -> int;) - val ~? = _prim "Word32_neg": int -> int; - val ~ = - if Controls.detectOverflow - then ~! - else ~? + val +? = _prim "WordS32_addCheckP": int * int -> bool; + val +! = _prim "Word32_add": int * int -> int; + val +$ = if Controls.newOverflow then + Exn.mkOverflow (+!, +?) + else + Exn.wrapOverflow (_prim "WordS32_addCheck": int * int -> int;) + val + = if Controls.detectOverflow then +$ else +! + + val *? = _prim "WordS32_mulCheckP": int * int -> bool; + val *! = _prim "WordS32_mul": int * int -> int; + val *$ = if Controls.newOverflow then + Exn.mkOverflow ( *!, *? ) + else + Exn.wrapOverflow (_prim "WordS32_mulCheck": int * int -> int;) + val * = if Controls.detectOverflow then *$ else *! + + val ~? = _prim "Word32_negCheckP": int -> bool; + val ~! = _prim "Word32_neg": int -> int; + val ~$ = if Controls.newOverflow then + Exn.mkOverflow (~!, ~?) + else + Exn.wrapOverflow (_prim "Word32_negCheck": int -> int;) + val ~ = if Controls.detectOverflow then ~$ else ~! + val quotUnsafe = _prim "WordS32_quot": int * int -> int; - val -! = Exn.wrapOverflow (_prim "WordS32_subCheck": int * int -> int;) - val -? = _prim "Word32_sub": int * int -> int; - val - = - if Controls.detectOverflow - then -! - else -? + + val -? = _prim "WordS32_subCheckP": int * int -> bool; + val -! = _prim "Word32_sub": int * int -> int; + val -$ = if Controls.newOverflow then + Exn.mkOverflow (-!, -?) + else + Exn.wrapOverflow (_prim "WordS32_subCheck": int * int -> int;) + val - = if Controls.detectOverflow then -$ else -! + val remUnsafe = _prim "WordS32_rem": int * int -> int; val < = _prim "WordS32_lt": int * int -> bool; @@ -427,31 +458,40 @@ structure Int64 = IntWordConv.zextdFromInt32ToWord32 sizeInBits val precision = SOME sizeInBits - val +! = Exn.wrapOverflow (_prim "WordS64_addCheck": int * int -> int;) - val +? = _prim "Word64_add": int * int -> int; - val + = - if Controls.detectOverflow - then +! - else +? - val *! = Exn.wrapOverflow (_prim "WordS64_mulCheck": int * int -> int;) - val *? = _prim "WordS64_mul": int * int -> int; - val * = - if Controls.detectOverflow - then *! - else *? - val ~! = Exn.wrapOverflow (_prim "Word64_negCheck": int -> int;) - val ~? = _prim "Word64_neg": int -> int; - val ~ = - if Controls.detectOverflow - then ~! - else ~? + val +? = _prim "WordS64_addCheckP": int * int -> bool; + val +! = _prim "Word64_add": int * int -> int; + val +$ = if Controls.newOverflow then + Exn.mkOverflow (+!, +?) + else + Exn.wrapOverflow (_prim "WordS64_addCheck": int * int -> int;) + val + = if Controls.detectOverflow then +$ else +! + + val *? = _prim "WordS64_mulCheckP": int * int -> bool; + val *! = _prim "WordS64_mul": int * int -> int; + val *$ = if Controls.newOverflow then + Exn.mkOverflow ( *!, *? ) + else + Exn.wrapOverflow (_prim "WordS64_mulCheck": int * int -> int;) + val * = if Controls.detectOverflow then *$ else *! + + val ~? = _prim "Word64_negCheckP": int -> bool; + val ~! = _prim "Word64_neg": int -> int; + val ~$ = if Controls.newOverflow then + Exn.mkOverflow (~!, ~?) + else + Exn.wrapOverflow (_prim "Word64_negCheck": int -> int;) + val ~ = if Controls.detectOverflow then ~$ else ~! + val quotUnsafe = _prim "WordS64_quot": int * int -> int; - val -! = Exn.wrapOverflow (_prim "WordS64_subCheck": int * int -> int;) - val -? = _prim "Word64_sub": int * int -> int; - val - = - if Controls.detectOverflow - then -! - else -? + + val -? = _prim "WordS64_subCheckP": int * int -> bool; + val -! = _prim "Word64_sub": int * int -> int; + val -$ = if Controls.newOverflow then + Exn.mkOverflow (-!, -?) + else + Exn.wrapOverflow (_prim "WordS64_subCheck": int * int -> int;) + val - = if Controls.detectOverflow then -$ else -! + val remUnsafe = _prim "WordS64_rem": int * int -> int; val < = _prim "WordS64_lt": int * int -> bool; diff --git a/basis-library/primitive/prim1.sml b/basis-library/primitive/prim1.sml index 9541d5002d..718548bec8 100644 --- a/basis-library/primitive/prim1.sml +++ b/basis-library/primitive/prim1.sml @@ -32,6 +32,7 @@ structure Controls = struct val debug = _command_line_const "MLton.debug": bool = false; val detectOverflow = _command_line_const "MLton.detectOverflow": bool = true; + val newOverflow = _command_line_const "MLton.newOverflow": bool = false; val safe = _command_line_const "MLton.safe": bool = true; val bufSize = _command_line_const "TextIO.bufSize": Int32.int = 4096; end @@ -52,6 +53,11 @@ structure Exn = exception Span exception Subscript + val mkOverflow: ('a -> 'b) * ('a -> bool) -> ('a -> 'b) = + fn (!, ?) => fn a => + let val r = ! a + in if ? a then raise Overflow else r + end val wrapOverflow: ('a -> 'b) -> ('a -> 'b) = fn f => fn a => f a handle PrimOverflow => raise Overflow end diff --git a/basis-library/text/char.sml b/basis-library/text/char.sml index 7f27eeff2a..01ddfed71a 100644 --- a/basis-library/text/char.sml +++ b/basis-library/text/char.sml @@ -103,7 +103,7 @@ functor CharFn(Arg : CHAR_ARG) local fun make (test, diff) c = - if test c then chrUnsafe (Int.+? (ord c, diff)) else c + if test c then chrUnsafe (Int.+! (ord c, diff)) else c val diff = Int.- (ord lA, ord la) in val toLower = make (isUpper, Int.~ diff) @@ -115,7 +115,7 @@ functor CharFn(Arg : CHAR_ARG) NONE => NONE | SOME (c, state) => if Char.<= (#"@", c) andalso Char.<= (c, #"_") - then SOME (chr (Int.-? (Char.ord c, Char.ord #"@")), state) + then SOME (chr (Int.-! (Char.ord c, Char.ord #"@")), state) else NONE fun formatChar reader state = @@ -274,7 +274,7 @@ functor CharFn(Arg : CHAR_ARG) fun padLeft (s: String.string, n: int): String.string = let val m = String.size s - val diff = Int.-? (n, m) + val diff = Int.-! (n, m) in if Int.> (diff, 0) then String.concat [String.new (diff, #"0"), s] else if diff = 0 @@ -314,7 +314,7 @@ functor CharFn(Arg : CHAR_ARG) then String.concat ["\\^", String.new (1, Char.chrUnsafe - (Int.+? (ord, 64 (* #"@" *) )))] + (Int.+! (ord, 64 (* #"@" *) )))] else if Int.< (ord, 256) then String.concat ["\\", padLeft (Int.fmt StringCvt.DEC ord, 3)] diff --git a/basis-library/text/string-cvt.sml b/basis-library/text/string-cvt.sml index 71489794f7..bf643d0412 100644 --- a/basis-library/text/string-cvt.sml +++ b/basis-library/text/string-cvt.sml @@ -38,7 +38,7 @@ structure StringCvt: STRING_CVT_EXTRA = in if n >= i then s - else f (s, String.vector (i -? n, c)) + else f (s, String.vector (i -! n, c)) end in val padLeft = pad (fn (s, pad) => String.^ (pad, s)) @@ -82,7 +82,7 @@ structure StringCvt: STRING_CVT_EXTRA = fun range (add: int, cmin: char, cmax: char): char -> int option = let val min = Char.ord cmin in fn c => if Char.<= (cmin, c) andalso Char.<= (c, cmax) - then SOME (add +? Char.ord c -? min) + then SOME (add +! Char.ord c -! min) else NONE end @@ -146,7 +146,7 @@ structure StringCvt: STRING_CVT_EXTRA = | SOME (c, state) => case charToDigit radix c of NONE => NONE - | SOME n => digits (radix, max -? 1, n) reader state + | SOME n => digits (radix, max -! 1, n) reader state fun digitsExact (radix, num) reader state = let val r = radixToInt radix diff --git a/basis-library/top-level/infixes-overflow.sml b/basis-library/top-level/infixes-overflow.sml index f34650b7dc..d1b389735f 100644 --- a/basis-library/top-level/infixes-overflow.sml +++ b/basis-library/top-level/infixes-overflow.sml @@ -6,5 +6,5 @@ * See the file MLton-LICENSE for details. *) -infix 7 *! -infix 6 +! -! +infix 7 *? *$ +infix 6 +? +$ -? -$ diff --git a/basis-library/top-level/infixes-unsafe.sml b/basis-library/top-level/infixes-unsafe.sml index 14a50df55d..be6e2dbcb7 100644 --- a/basis-library/top-level/infixes-unsafe.sml +++ b/basis-library/top-level/infixes-unsafe.sml @@ -6,5 +6,5 @@ * See the file MLton-LICENSE for details. *) -infix 7 *? -infix 6 +? -? +infix 7 *! +infix 6 +! -! diff --git a/basis-library/util/CUtil.sml b/basis-library/util/CUtil.sml index 0e4dfb0c93..18e8cf845a 100644 --- a/basis-library/util/CUtil.sml +++ b/basis-library/util/CUtil.sml @@ -17,7 +17,7 @@ structure CUtil: C_UTIL = fun loop i = if term (sub (p, i)) then i - else loop (i +? 1) + else loop (i +! 1) in loop 0 end @@ -96,7 +96,7 @@ structure CUtil: C_UTIL = let val (a, _) = Array.unfoldi - (1 +? List.length l, l, fn (_, l) => + (1 +! List.length l, l, fn (_, l) => case l of [] => (NullString.empty, l) | s::l => (NullString.nullTerm s, l)) diff --git a/include/amd64-main.h b/include/amd64-main.h index f47be6dac3..3b75f48481 100644 --- a/include/amd64-main.h +++ b/include/amd64-main.h @@ -23,6 +23,7 @@ PRIVATE Word64 fpcvtTemp; PRIVATE Word32 fpeqTemp; PRIVATE Word64 divTemp; PRIVATE Word64 indexTemp; +PRIVATE Word64 overflowCheckTemp; PRIVATE Word64 raTemp1; PRIVATE Word64 spill[32]; PRIVATE Word64 stackTopTemp; diff --git a/include/x86-main.h b/include/x86-main.h index c1790a755d..0c2175d6c9 100644 --- a/include/x86-main.h +++ b/include/x86-main.h @@ -21,6 +21,7 @@ PRIVATE Word32 divTemp; PRIVATE Word32 fildTemp; PRIVATE Word32 fpswTemp; PRIVATE Word32 indexTemp; +PRIVATE Word32 overflowCheckTemp; PRIVATE Word32 raTemp1; PRIVATE Real64 raTemp2; PRIVATE Real64 realTemp1D; diff --git a/mlton/atoms/prim.fun b/mlton/atoms/prim.fun index 9b63b18247..d2a82a5700 100644 --- a/mlton/atoms/prim.fun +++ b/mlton/atoms/prim.fun @@ -167,6 +167,7 @@ datatype 'a t = | Weak_new (* to rssa (as runtime C fn) *) | Word_add of WordSize.t (* codegen *) | Word_addCheck of WordSize.t * {signed: bool} (* codegen *) + | Word_addCheckP of WordSize.t * {signed: bool} (* codegen *) | Word_andb of WordSize.t (* codegen *) | Word_castToReal of WordSize.t * RealSize.t (* codegen *) | Word_equal of WordSize.t (* codegen *) @@ -175,8 +176,10 @@ datatype 'a t = | Word_lt of WordSize.t * {signed: bool} (* codegen *) | Word_mul of WordSize.t * {signed: bool} (* codegen *) | Word_mulCheck of WordSize.t * {signed: bool} (* codegen *) + | Word_mulCheckP of WordSize.t * {signed: bool} (* codegen *) | Word_neg of WordSize.t (* codegen *) | Word_negCheck of WordSize.t (* codegen *) + | Word_negCheckP of WordSize.t (* codegen *) | Word_notb of WordSize.t (* codegen *) | Word_orb of WordSize.t (* codegen *) | Word_quot of WordSize.t * {signed: bool} (* codegen *) @@ -187,6 +190,7 @@ datatype 'a t = | Word_rshift of WordSize.t * {signed: bool} (* codegen *) | Word_sub of WordSize.t (* codegen *) | Word_subCheck of WordSize.t * {signed: bool} (* codegen *) + | Word_subCheckP of WordSize.t * {signed: bool} (* codegen *) | Word_toIntInf (* to rssa *) | Word_xorb of WordSize.t (* codegen *) | WordVector_toIntInf (* to rssa *) @@ -344,6 +348,7 @@ fun toString (n: 'a t): string = | WordVector_toIntInf => "WordVector_toIntInf" | Word_add s => word (s, "add") | Word_addCheck (s, sg) => wordS (s, sg, "addCheck") + | Word_addCheckP (s, sg) => wordS (s, sg, "addCheckP") | Word_andb s => word (s, "andb") | Word_castToReal (s1, s2) => cast (wordC, realC, s1, s2) | Word_equal s => word (s, "equal") @@ -352,8 +357,10 @@ fun toString (n: 'a t): string = | Word_lt (s, sg) => wordS (s, sg, "lt") | Word_mul (s, sg) => wordS (s, sg, "mul") | Word_mulCheck (s, sg) => wordS (s, sg, "mulCheck") + | Word_mulCheckP (s, sg) => wordS (s, sg, "mulCheckP") | Word_neg s => word (s, "neg") | Word_negCheck s => word (s, "negCheck") + | Word_negCheckP s => word (s, "negCheckP") | Word_notb s => word (s, "notb") | Word_orb s => word (s, "orb") | Word_quot (s, sg) => wordS (s, sg, "quot") @@ -364,6 +371,7 @@ fun toString (n: 'a t): string = | Word_rshift (s, sg) => wordS (s, sg, "rshift") | Word_sub s => word (s, "sub") | Word_subCheck (s, sg) => wordS (s, sg, "subCheck") + | Word_subCheckP (s, sg) => wordS (s, sg, "subCheckP") | Word_toIntInf => "Word_toIntInf" | Word_xorb s => word (s, "xorb") | World_save => "World_save" @@ -671,6 +679,7 @@ val map: 'a t * ('a -> 'b) -> 'b t = | Weak_new => Weak_new | Word_add z => Word_add z | Word_addCheck z => Word_addCheck z + | Word_addCheckP z => Word_addCheckP z | Word_andb z => Word_andb z | Word_castToReal z => Word_castToReal z | Word_equal z => Word_equal z @@ -679,8 +688,10 @@ val map: 'a t * ('a -> 'b) -> 'b t = | Word_lt z => Word_lt z | Word_mul z => Word_mul z | Word_mulCheck z => Word_mulCheck z + | Word_mulCheckP z => Word_mulCheckP z | Word_neg z => Word_neg z | Word_negCheck z => Word_negCheck z + | Word_negCheckP z => Word_negCheckP z | Word_notb z => Word_notb z | Word_orb z => Word_orb z | Word_quot z => Word_quot z @@ -691,6 +702,7 @@ val map: 'a t * ('a -> 'b) -> 'b t = | Word_rshift z => Word_rshift z | Word_sub z => Word_sub z | Word_subCheck z => Word_subCheck z + | Word_subCheckP z => Word_subCheckP z | Word_toIntInf => Word_toIntInf | Word_xorb z => Word_xorb z | WordVector_toIntInf => WordVector_toIntInf @@ -792,10 +804,12 @@ val isCommutative = | Real_qequal _ => true | Word_add _ => true | Word_addCheck _ => true + | Word_addCheckP _ => true | Word_andb _ => true | Word_equal _ => true | Word_mul _ => true | Word_mulCheck _ => true + | Word_mulCheckP _ => true | Word_orb _ => true | Word_xorb _ => true | _ => false @@ -933,6 +947,7 @@ val kind: 'a t -> Kind.t = | WordVector_toIntInf => Functional | Word_add _ => Functional | Word_addCheck _ => SideEffect + | Word_addCheckP _ => Functional | Word_andb _ => Functional | Word_castToReal _ => Functional | Word_equal _ => Functional @@ -941,8 +956,10 @@ val kind: 'a t -> Kind.t = | Word_lt _ => Functional | Word_mul _ => Functional | Word_mulCheck _ => SideEffect + | Word_mulCheckP _ => Functional | Word_neg _ => Functional | Word_negCheck _ => SideEffect + | Word_negCheckP _ => Functional | Word_notb _ => Functional | Word_orb _ => Functional | Word_quot _ => Functional @@ -953,6 +970,7 @@ val kind: 'a t -> Kind.t = | Word_rshift _ => Functional | Word_sub _ => Functional | Word_subCheck _ => SideEffect + | Word_subCheckP _ => Functional | Word_toIntInf => Functional | Word_xorb _ => Functional | World_save => SideEffect @@ -995,13 +1013,16 @@ local val sg = {signed = signed} in List.map ([Word_addCheck, + Word_addCheckP, Word_lt, Word_mul, Word_mulCheck, + Word_mulCheckP, Word_quot, Word_rem, Word_rshift, - Word_subCheck], + Word_subCheck, + Word_subCheckP], fn p => p (s, sg)) end @@ -1012,6 +1033,7 @@ local (Word_lshift s), (Word_neg s), (Word_negCheck s), + (Word_negCheckP s), (Word_notb s), (Word_orb s), (Word_rol s), @@ -1243,6 +1265,13 @@ fun 'a checkApp (prim: 'a t, val realUnary = make real val wordUnary = make word end + local + fun make f s = let val t = f s + in noTargs (fn () => (oneArg t, bool)) + end + in + val wordUnaryP = make word + end local fun make f s = let val t = f s in noTargs (fn () => (twoArgs (t, t), t)) @@ -1258,6 +1287,7 @@ fun 'a checkApp (prim: 'a t, in val realCompare = make real val wordCompare = make word + val wordBinaryP = make word end val cint = word (WordSize.cint ()) val compareRes = word WordSize.compareRes @@ -1435,6 +1465,7 @@ fun 'a checkApp (prim: 'a t, noTargs (fn () => (oneArg (vector bigIntInfWord), intInf)) | Word_add s => wordBinary s | Word_addCheck (s, _) => wordBinary s + | Word_addCheckP (s, _) => wordBinaryP s | Word_andb s => wordBinary s | Word_castToReal (s, s') => noTargs (fn () => (oneArg (word s), real s')) @@ -1445,8 +1476,10 @@ fun 'a checkApp (prim: 'a t, | Word_lt (s, _) => wordCompare s | Word_mul (s, _) => wordBinary s | Word_mulCheck (s, _) => wordBinary s + | Word_mulCheckP (s, _) => wordBinaryP s | Word_neg s => wordUnary s | Word_negCheck s => wordUnary s + | Word_negCheckP s => wordUnaryP s | Word_notb s => wordUnary s | Word_orb s => wordBinary s | Word_quot (s, _) => wordBinary s @@ -1458,6 +1491,7 @@ fun 'a checkApp (prim: 'a t, | Word_rshift (s, _) => wordShift s | Word_sub s => wordBinary s | Word_subCheck (s, _) => wordBinary s + | Word_subCheckP (s, _) => wordBinaryP s | Word_toIntInf => noTargs (fn () => (oneArg smallIntInfWord, intInf)) | Word_xorb s => wordBinary s | World_save => noTargs (fn () => (oneArg string, unit)) @@ -1649,15 +1683,22 @@ fun ('a, 'b) apply (p: 'a t, if WordSize.isInRange (s, w, sg) then word (WordX.fromIntInf (w, s)) else ApplyResult.Overflow - fun wcheck (f: IntInf.t * IntInf.t -> IntInf.t, - (s: WordSize.t, sg as {signed}), - w: WordX.t, - w': WordX.t) = - let - val conv = if signed then WordX.toIntInfX else WordX.toIntInf - in - wordOrOverflow (s, sg, f (conv w, conv w')) - end + fun wordOrTrue (s, sg, w) = bool (not (WordSize.isInRange (s, w, sg))) + local + fun mkCheck toAppRes = + fn (f: IntInf.t * IntInf.t -> IntInf.t, + (s: WordSize.t, sg as {signed}), + w: WordX.t, + w': WordX.t) => + let + val conv = if signed then WordX.toIntInfX else WordX.toIntInf + in + toAppRes (s, sg, f (conv w, conv w')) + end + in + val wcheck = mkCheck wordOrOverflow + val wcheckp = mkCheck wordOrTrue + end val eq = fn (Word w1, Word w2) => bool (WordX.equals (w1, w2)) | _ => ApplyResult.Unknown @@ -1791,15 +1832,19 @@ fun ('a, 'b) apply (p: 'a t, (if signed then WordX.toIntInfX w else WordX.toIntInf w, s)) | (Word_add _, [Word w1, Word w2]) => word (WordX.add (w1, w2)) | (Word_addCheck s, [Word w1, Word w2]) => wcheck (op +, s, w1, w2) + | (Word_addCheckP s, [Word w1, Word w2]) => wcheckp (op +, s, w1, w2) | (Word_andb _, [Word w1, Word w2]) => word (WordX.andb (w1, w2)) | (Word_equal _, [Word w1, Word w2]) => bool (WordX.equals (w1, w2)) | (Word_lshift _, [Word w1, Word w2]) => word (WordX.lshift (w1, w2)) | (Word_lt s, [Word w1, Word w2]) => wordCmp (WordX.lt, s, w1, w2) | (Word_mul s, [Word w1, Word w2]) => wordS (WordX.mul, s, w1, w2) | (Word_mulCheck s, [Word w1, Word w2]) => wcheck (op *, s, w1, w2) + | (Word_mulCheckP s, [Word w1, Word w2]) => wcheckp (op *, s, w1, w2) | (Word_neg _, [Word w]) => word (WordX.neg w) | (Word_negCheck s, [Word w]) => wordOrOverflow (s, {signed = true}, ~ (WordX.toIntInfX w)) + | (Word_negCheckP s, [Word w]) => + wordOrTrue (s, {signed = true}, ~ (WordX.toIntInfX w)) | (Word_notb _, [Word w]) => word (WordX.notb w) | (Word_orb _, [Word w1, Word w2]) => word (WordX.orb (w1, w2)) | (Word_quot s, [Word w1, Word w2]) => @@ -1816,6 +1861,7 @@ fun ('a, 'b) apply (p: 'a t, wordS (WordX.rshift, s, w1, w2) | (Word_sub _, [Word w1, Word w2]) => word (WordX.sub (w1, w2)) | (Word_subCheck s, [Word w1, Word w2]) => wcheck (op -, s, w1, w2) + | (Word_subCheckP s, [Word w1, Word w2]) => wcheckp (op -, s, w1, w2) | (Word_toIntInf, [Word w]) => (case IntInfRep.smallToIntInf w of NONE => ApplyResult.Unknown @@ -2005,6 +2051,10 @@ fun ('a, 'b) apply (p: 'a t, else Unknown | Word_add _ => add () | Word_addCheck _ => add () + | Word_addCheckP _ => + if WordX.isZero w + then f + else Unknown | Word_andb s => if WordX.isZero w then zero s @@ -2018,6 +2068,10 @@ fun ('a, 'b) apply (p: 'a t, else if WordX.isMax (w, sg) then f else Unknown | Word_mul s => mul (s, wordNeg) | Word_mulCheck s => mul (s, wordNegCheck) + | Word_mulCheckP _ => + if WordX.isZero w orelse WordX.isOne w + then f + else Unknown | Word_orb _ => if WordX.isZero w then Var x @@ -2053,6 +2107,10 @@ fun ('a, 'b) apply (p: 'a t, shift s | Word_sub s => sub (s, wordNeg) | Word_subCheck s => sub (s, wordNegCheck o #1) + | Word_subCheckP _ => + if WordX.isZero w andalso inOrder + then f + else Unknown | Word_xorb s => if WordX.isZero w then Var x diff --git a/mlton/atoms/prim.sig b/mlton/atoms/prim.sig index 08adc45dfb..98f0fabe79 100644 --- a/mlton/atoms/prim.sig +++ b/mlton/atoms/prim.sig @@ -159,6 +159,7 @@ signature PRIM = | Weak_new (* to rssa (as runtime C fn) *) | Word_add of WordSize.t (* codegen *) | Word_addCheck of WordSize.t * {signed: bool} (* codegen *) + | Word_addCheckP of WordSize.t * {signed: bool} (* codegen *) | Word_andb of WordSize.t (* codegen *) | Word_castToReal of WordSize.t * RealSize.t (* codegen *) | Word_equal of WordSize.t (* codegen *) @@ -167,8 +168,10 @@ signature PRIM = | Word_lt of WordSize.t * {signed: bool} (* codegen *) | Word_mul of WordSize.t * {signed: bool} (* codegen *) | Word_mulCheck of WordSize.t * {signed: bool} (* codegen *) + | Word_mulCheckP of WordSize.t * {signed: bool} (* codegen *) | Word_neg of WordSize.t (* codegen *) | Word_negCheck of WordSize.t (* codegen *) + | Word_negCheckP of WordSize.t (* codegen *) | Word_notb of WordSize.t (* codegen *) | Word_orb of WordSize.t (* codegen *) | Word_quot of WordSize.t * {signed: bool} (* codegen *) @@ -179,6 +182,7 @@ signature PRIM = | Word_rshift of WordSize.t * {signed: bool} (* codegen *) | Word_sub of WordSize.t (* codegen *) | Word_subCheck of WordSize.t * {signed: bool} (* codegen *) + | Word_subCheckP of WordSize.t * {signed: bool} (* codegen *) | Word_toIntInf (* to rssa *) | Word_xorb of WordSize.t (* codegen *) | WordVector_toIntInf (* to rssa *) diff --git a/mlton/backend/rep-type.fun b/mlton/backend/rep-type.fun index 48b0369106..b992907895 100644 --- a/mlton/backend/rep-type.fun +++ b/mlton/backend/rep-type.fun @@ -571,6 +571,11 @@ fun checkPrimApp {args, prim, result} = val realUnary = make real val wordUnary = make wordOrBitsOrSeq end + local + fun make f s = let val t = f s in done ([t], SOME bool) end + in + val wordUnaryP = make wordOrBitsOrSeq + end local fun make f s = let val t = f s in done ([t, t], SOME t) end in @@ -581,6 +586,7 @@ fun checkPrimApp {args, prim, result} = fun make f s = let val t = f s in done ([t, t], SOME bool) end in val realCompare = make real + val wordBinaryP = make wordOrBitsOrSeq val wordCompare = make wordOrBitsOrSeq val objptrCompare = make (fn _ => objptr) () end @@ -631,6 +637,7 @@ fun checkPrimApp {args, prim, result} = | Thread_returnToC => done ([], NONE) | Word_add s => wordBinary s | Word_addCheck (s, _) => wordBinary s + | Word_addCheckP (s, _) => wordBinaryP s | Word_andb s => wordBinary s | Word_castToReal (s, s') => done ([word s], SOME (real s')) | Word_equal s => (wordCompare s) orelse objptrCompare @@ -640,8 +647,10 @@ fun checkPrimApp {args, prim, result} = | Word_lt (s, _) => wordCompare s | Word_mul (s, _) => wordBinary s | Word_mulCheck (s, _) => wordBinary s + | Word_mulCheckP (s, _) => wordBinaryP s | Word_neg s => wordUnary s | Word_negCheck s => wordUnary s + | Word_negCheckP s => wordUnaryP s | Word_notb s => wordUnary s | Word_orb s => wordBinary s | Word_quot (s, _) => wordBinary s @@ -652,6 +661,7 @@ fun checkPrimApp {args, prim, result} = | Word_rshift (s, _) => wordShift s | Word_sub s => wordBinary s | Word_subCheck (s, _) => wordBinary s + | Word_subCheckP (s, _) => wordBinaryP s | Word_xorb s => wordBinary s | _ => Error.bug (concat ["RepType.checkPrimApp got strange prim: ", Prim.toString prim]) diff --git a/mlton/backend/ssa-to-rssa.fun b/mlton/backend/ssa-to-rssa.fun index 3cba77ec48..98c4a84194 100644 --- a/mlton/backend/ssa-to-rssa.fun +++ b/mlton/backend/ssa-to-rssa.fun @@ -466,21 +466,33 @@ structure Name = prototype = (Vector.new (n, ct), SOME ct), return = t} end - fun makeOverflows n (s, sg) = + fun makeCheck n (s, sg) = let val t = word s val ct = CType.word (s, sg) in vanilla {args = Vector.new (n, t), - name = name ^ "Overflows", + name = name ^ "P", + prototype = (Vector.new (n, ct), SOME CType.bool), + return = Type.bool} + end + fun makeCheckP n (s, sg) = + let + val t = word s + val ct = CType.word (s, sg) + in + vanilla {args = Vector.new (n, t), + name = name, prototype = (Vector.new (n, ct), SOME CType.bool), return = Type.bool} end in val wordBinary = make 2 - val wordBinaryOverflows = makeOverflows 2 + val wordBinaryCheck = makeCheck 2 + val wordBinaryCheckP = makeCheckP 2 val wordUnary = make 1 - val wordUnaryOverflows = makeOverflows 1 + val wordUnaryCheck = makeCheck 1 + val wordUnaryCheckP = makeCheckP 1 end fun wordCompare (s, sg) = let @@ -550,7 +562,8 @@ structure Name = | Real_sub s => realBinary s | Thread_returnToC => CFunction.returnToC () | Word_add s => wordBinary (s, {signed = false}) - | Word_addCheck (s, sg) => wordBinaryOverflows (s, sg) + | Word_addCheck (s, sg) => wordBinaryCheck (s, sg) + | Word_addCheckP (s, sg) => wordBinaryCheckP (s, sg) | Word_andb s => wordBinary (s, {signed = false}) | Word_castToReal (s1, s2) => coerce (word s1, wordCType (s1, {signed = false}), @@ -562,9 +575,11 @@ structure Name = | Word_lshift s => wordShift (s, {signed = false}) | Word_lt z => wordCompare z | Word_mul z => wordBinary z - | Word_mulCheck (s, sg) => wordBinaryOverflows (s, sg) + | Word_mulCheck (s, sg) => wordBinaryCheck (s, sg) + | Word_mulCheckP (s, sg) => wordBinaryCheckP (s, sg) | Word_neg s => wordUnary (s, {signed = true}) - | Word_negCheck s => wordUnaryOverflows (s, {signed = true}) + | Word_negCheck s => wordUnaryCheck (s, {signed = true}) + | Word_negCheckP s => wordUnaryCheckP (s, {signed = true}) | Word_notb s => wordUnary (s, {signed = false}) | Word_orb s => wordBinary (s, {signed = false}) | Word_quot z => wordBinary z @@ -577,7 +592,8 @@ structure Name = | Word_ror s => wordShift (s, {signed = false}) | Word_rshift z => wordShift z | Word_sub s => wordBinary (s, {signed = false}) - | Word_subCheck (s, sg) => wordBinaryOverflows (s, sg) + | Word_subCheck (s, sg) => wordBinaryCheck (s, sg) + | Word_subCheckP (s, sg) => wordBinaryCheckP (s, sg) | _ => Error.bug "SsaToRssa.Name.cFunctionRaise" end diff --git a/mlton/codegen/amd64-codegen/amd64-mlton-basic.fun b/mlton/codegen/amd64-codegen/amd64-mlton-basic.fun index 78feef44ee..7828aee684 100644 --- a/mlton/codegen/amd64-codegen/amd64-mlton-basic.fun +++ b/mlton/codegen/amd64-codegen/amd64-mlton-basic.fun @@ -232,6 +232,14 @@ struct fun fpeqTempContentsOperand size = Operand.memloc (fpeqTempContents size) + val overflowCheckTemp = Label.fromString "overflowCheckTemp" + fun overflowCheckTempContents size + = makeContents {base = Immediate.label overflowCheckTemp, + size = size, + class = Classes.StaticTemp} + fun overflowCheckTempContentsOperand size + = Operand.memloc (overflowCheckTempContents size) + local fun make prefix = let diff --git a/mlton/codegen/amd64-codegen/amd64-mlton-basic.sig b/mlton/codegen/amd64-codegen/amd64-mlton-basic.sig index 2fa7281202..3977e62261 100644 --- a/mlton/codegen/amd64-codegen/amd64-mlton-basic.sig +++ b/mlton/codegen/amd64-codegen/amd64-mlton-basic.sig @@ -90,6 +90,7 @@ signature AMD64_MLTON_BASIC = val applyFFTempXmmRegArgContents : amd64.Size.t * int -> amd64.MemLoc.t val fpcvtTempContentsOperand : amd64.Operand.t val fpeqTempContentsOperand : amd64.Size.t -> amd64.Operand.t + val overflowCheckTempContentsOperand : amd64.Size.t -> amd64.Operand.t (* Static arrays defined in main.h and amd64-main.h *) val local_base : amd64.CType.t -> amd64.Label.t diff --git a/mlton/codegen/amd64-codegen/amd64-mlton.fun b/mlton/codegen/amd64-codegen/amd64-mlton.fun index 02b37a2bc3..310ec04c4d 100644 --- a/mlton/codegen/amd64-codegen/amd64-mlton.fun +++ b/mlton/codegen/amd64-codegen/amd64-mlton.fun @@ -80,6 +80,7 @@ struct | Thread_returnToC => false | Word_add _ => true | Word_addCheck _ => true + | Word_addCheckP _ => true | Word_andb _ => true | Word_castToReal _ => true | Word_equal _ => true @@ -88,8 +89,10 @@ struct | Word_lt _ => true | Word_mul _ => true | Word_mulCheck _ => true + | Word_mulCheckP _ => true | Word_neg _ => true | Word_negCheck _ => true + | Word_negCheckP _ => true | Word_notb _ => true | Word_orb _ => true | Word_quot _ => true @@ -100,6 +103,7 @@ struct | Word_rshift _ => true | Word_sub _ => true | Word_subCheck _ => true + | Word_subCheckP _ => true | Word_xorb _ => true | _ => false end @@ -240,6 +244,60 @@ struct transfer = NONE}] end + fun binalcc (oper, condition) + = let + val ((src1,src1size), + (src2,src2size)) = getSrc2 () + val (dst,dstsize) = getDst1 () + val tmp = overflowCheckTempContentsOperand src1size + val _ + = Assert.assert + ("amd64MLton.prim: binalcc, src1size/src2size", + fn () => src1size = src2size) + + (* Reverse src1/src2 when src1 and src2 are temporaries + * and the oper is commutative. + *) + val (src1,src2) + = if (oper = Instruction.ADD) + orelse + (oper = Instruction.ADC) + orelse + (oper = Instruction.AND) + orelse + (oper = Instruction.OR) + orelse + (oper = Instruction.XOR) + then case (Operand.deMemloc src1, Operand.deMemloc src2) + of (SOME memloc_src1, SOME memloc_src2) + => if amd64Liveness.track memloc_src1 + andalso + amd64Liveness.track memloc_src2 + then (src2,src1) + else (src1,src2) + | _ => (src1,src2) + else (src1,src2) + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp, + src = src1, + size = src1size}, + Assembly.instruction_binal + {oper = oper, + dst = tmp, + src = src2, + size = src1size}, + Assembly.instruction_setcc + {condition = condition, + dst = dst, + size = dstsize}], + transfer = NONE}] + end + fun pmd oper = let val ((src1,src1size), @@ -284,6 +342,54 @@ struct transfer = NONE}] end + fun pmdcc (oper, condition) + = let + val ((src1,src1size), + (src2,src2size)) = getSrc2 () + val (dst,dstsize) = getDst1 () + val tmp = overflowCheckTempContentsOperand src1size + val _ + = Assert.assert + ("amd64MLton.prim: pmdcc, src1size/src2size", + fn () => src1size = src2size) + + (* Reverse src1/src2 when src1 and src2 are temporaries + * and the oper is commutative. + *) + val (src1,src2) + = if (oper = Instruction.IMUL) + orelse + (oper = Instruction.MUL) + then case (Operand.deMemloc src1, Operand.deMemloc src2) + of (SOME memloc_src1, SOME memloc_src2) + => if amd64Liveness.track memloc_src1 + andalso + amd64Liveness.track memloc_src2 + then (src2,src1) + else (src1,src2) + | _ => (src1,src2) + else (src1,src2) + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp, + src = src1, + size = src1size}, + Assembly.instruction_pmd + {oper = oper, + dst = tmp, + src = src2, + size = src1size}, + Assembly.instruction_setcc + {condition = condition, + dst = dst, + size = dstsize}], + transfer = NONE}] + end + fun imul2 () = let val ((src1,src1size), @@ -323,6 +429,49 @@ struct transfer = NONE}] end + fun imul2cc condition + = let + val ((src1,src1size), + (src2,src2size)) = getSrc2 () + val (dst,dstsize) = getDst1 () + val tmp = overflowCheckTempContentsOperand src1size + val _ + = Assert.assert + ("amd64MLton.prim: imul2cc, src1size/src2size", + fn () => src1size = src2size) + + (* Reverse src1/src2 when src1 and src2 are temporaries + * and the oper is commutative. + *) + val (src1,src2) + = case (Operand.deMemloc src1, Operand.deMemloc src2) + of (SOME memloc_src1, SOME memloc_src2) + => if amd64Liveness.track memloc_src1 + andalso + amd64Liveness.track memloc_src2 + then (src2,src1) + else (src1,src2) + | _ => (src1,src2) + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp, + src = src1, + size = src1size}, + Assembly.instruction_imul2 + {dst = tmp, + src = src2, + size = src1size}, + Assembly.instruction_setcc + {dst = dst, + condition = condition, + size = dstsize}], + transfer = NONE}] + end + fun unal oper = let val (src,srcsize) = getSrc1 () @@ -347,6 +496,31 @@ struct transfer = NONE}] end + fun unalcc (oper, condition) + = let + val (src,srcsize) = getSrc1 () + val (dst,dstsize) = getDst1 () + val tmp = overflowCheckTempContentsOperand srcsize + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp, + src = src, + size = srcsize}, + Assembly.instruction_unal + {oper = oper, + dst = tmp, + size = srcsize}, + Assembly.instruction_setcc + {condition = condition, + dst = dst, + size = dstsize}], + transfer = NONE}] + end + fun sral oper = let val (dst,dstsize) = getDst1 () @@ -611,6 +785,9 @@ struct transfer = NONE})) end else (AppendList.empty,AppendList.empty) + + fun flag {signed} = + if signed then amd64.Instruction.O else amd64.Instruction.C in AppendList.appends [comment_begin, @@ -991,6 +1168,7 @@ struct end | Real_sub _ => sse_binas Instruction.SSE_SUBS | Word_add _ => binal Instruction.ADD + | Word_addCheckP (_, sg) => binalcc (Instruction.ADD, flag sg) | Word_andb _ => binal Instruction.AND | Word_castToReal _ => sse_movd () | Word_equal _ => cmp Instruction.E @@ -1004,7 +1182,17 @@ struct | W16 => imul2 () | W32 => imul2 () | W64 => imul2 ()) + | Word_mulCheckP (s, {signed}) => + if signed then + (case WordSize.prim s of + W8 => pmdcc (Instruction.IMUL, amd64.Instruction.O) + | W16 => imul2cc amd64.Instruction.O + | W32 => imul2cc amd64.Instruction.O + | W64 => imul2cc amd64.Instruction.O) + else + pmdcc (Instruction.MUL, amd64.Instruction.C) | Word_neg _ => unal Instruction.NEG + | Word_negCheckP _ => unalcc (Instruction.NEG, Instruction.O) | Word_notb _ => unal Instruction.NOT | Word_orb _ => binal Instruction.OR | Word_quot (_, {signed}) => @@ -1069,6 +1257,7 @@ struct | Word_rshift (_, {signed}) => sral (if signed then Instruction.SAR else Instruction.SHR) | Word_sub _ => binal Instruction.SUB + | Word_subCheckP (_, sg) => binalcc (Instruction.SUB, flag sg) | Word_extdToWord (s, s', {signed}) => let val b = WordSize.bits s diff --git a/mlton/codegen/amd64-codegen/amd64-simplify.fun b/mlton/codegen/amd64-codegen/amd64-simplify.fun index a5ed7d265d..7401c88d14 100644 --- a/mlton/codegen/amd64-codegen/amd64-simplify.fun +++ b/mlton/codegen/amd64-codegen/amd64-simplify.fun @@ -561,6 +561,9 @@ struct (Instruction.BinAL {oper = Instruction.SBB, ...}) => (true, if b then b' else true) + | Assembly.Instruction + (Instruction.MOV _) + => (b, b') | Assembly.Instruction (Instruction.SETcc {condition = Instruction.C, ...}) @@ -1514,7 +1517,7 @@ struct (* elimBinAL0L:: *) (* elimBinAL0R:: *) elimAddSub1:: - elimMDPow2:: +(* elimMDPow2:: *) elimCMPTEST:: nil val optimizations_pre_msg @@ -1522,18 +1525,20 @@ struct (* elimBinAL0L_msg:: *) (* elimBinAL0R_msg:: *) elimAddSub1_msg:: - elimMDPow2_msg:: +(* elimMDPow2_msg:: *) nil val optimizations_post - = elimBinALMDDouble:: + = elimMDPow2:: + elimBinALMDDouble:: elimSSEBinASDouble:: elimCMPTEST:: elimCMP0:: elimALTEST:: nil val optimizations_post_msg - = elimBinALMDDouble_msg:: + = elimMDPow2_msg:: + elimBinALMDDouble_msg:: elimSSEBinASDouble_msg:: elimCMPTEST_msg:: elimCMP0_msg:: @@ -2845,6 +2850,15 @@ struct (finish, (false, false), fn ((asm, _), (b, b')) => case asm of Assembly.Comment _ => (b, b') + | Assembly.Instruction + (Instruction.BinAL {oper = Instruction.ADC, ...}) + => (true, if b then b' else true) + | Assembly.Instruction + (Instruction.BinAL {oper = Instruction.SBB, ...}) + => (true, if b then b' else true) + | Assembly.Instruction + (Instruction.MOV _) + => (b, b') | Assembly.Instruction (Instruction.SETcc _) => (true, if b then b' else true) @@ -3087,6 +3101,158 @@ struct val elimALCopy_msg = elimALCopy_msg end + local + fun isInstructionMOV_aux (check) : statement_type -> bool + = fn (Assembly.Instruction (Instruction.MOV + {dst = Operand.MemLoc memloc,...}), + _) + => check memloc + | _ => false + + val isInstructionMOV : statement_type -> bool + = isInstructionMOV_aux (fn _ => true) + val isInstructionMOV_dstTemp : statement_type -> bool + = isInstructionMOV_aux amd64Liveness.track + + fun isInstructionAL_aux (check) : statement_type -> bool + = fn (Assembly.Instruction (Instruction.BinAL + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | (Assembly.Instruction (Instruction.pMD + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | (Assembly.Instruction (Instruction.IMUL2 + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | (Assembly.Instruction (Instruction.UnAL + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | (Assembly.Instruction (Instruction.SRAL + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | _ => false + + val isInstructionAL : statement_type -> bool + = isInstructionAL_aux (fn _ => true) + + fun isDeadTemp dead memloc + = amd64Liveness.track memloc andalso LiveSet.contains (dead, memloc) + val isInstructionAL_dstDeadTemp : statement_type -> bool + = fn (instr, liveness as Liveness.T {dead, ...}) + => isInstructionAL_aux (isDeadTemp dead) (instr, liveness) + + val template : template + = {start = EmptyOrNonEmpty, + statements = [One isInstructionMOV, + All isComment, + One isInstructionAL, + All isComment, + One isInstructionMOV_dstTemp, + All isComment, + One isInstructionAL_dstDeadTemp], + finish = EmptyOrNonEmpty, + transfer = fn _ => true} + + val rewriter : rewriter + = fn {entry, + profileLabel, + start, + statements = + [[(stmtMov as Assembly.Instruction (Instruction.MOV + {src = src1x, + dst = dst1z, ...}), + _)], + comments1, + [(stmtAL as Assembly.Instruction instrAL1, _)], + comments2, + [(Assembly.Instruction (Instruction.MOV + {src = src2x, + dst = dst2z, ...}), + _)], + comments3, + [(Assembly.Instruction instrAL2, + Liveness.T {liveOut = liveOut2, ...})]], + finish, + transfer} + => if !Control.Native.elimALRedundant andalso + Operand.eq (src1x, src2x) andalso + (let + fun checkUn (oper1, dst1, oper2, dst2) + = oper1 = oper2 andalso + Operand.eq(dst1z, dst1) andalso + Operand.eq(dst2z, dst2) + + fun checkBin (oper1, src1, dst1, oper2, src2, dst2) + = oper1 = oper2 andalso + Operand.eq(src1, src2) andalso + Operand.eq(dst1z, dst1) andalso + Operand.eq(dst2z, dst2) + in + case (instrAL1, instrAL2) of + (Instruction.BinAL + {oper = oper1, src = src1, dst = dst1, ...}, + Instruction.BinAL + {oper = oper2, src = src2, dst = dst2, ...}) + => checkBin (oper1, src1, dst1, oper2, src2, dst2) + | (Instruction.pMD + {oper = oper1, src = src1, dst = dst1, ...}, + Instruction.pMD + {oper = oper2, src = src2, dst = dst2, ...}) + => checkBin (oper1, src1, dst1, oper2, src2, dst2) + | (Instruction.IMUL2 + {src = src1, dst = dst1, ...}, + Instruction.IMUL2 + {src = src2, dst = dst2, ...}) + => checkBin (Instruction.IMUL, src1, dst1, + Instruction.IMUL, src2, dst2) + | (Instruction.UnAL + {oper = oper1, dst = dst1, ...}, + Instruction.UnAL + {oper = oper2, dst = dst2, ...}) + => checkUn (oper1, dst1, oper2, dst2) + | (Instruction.SRAL + {oper = oper1, count = src1, dst = dst1, ...}, + Instruction.SRAL + {oper = oper2, count = src2, dst = dst2, ...}) + => checkBin (oper1, src1, dst1, oper2, src2, dst2) + | _ => false + end) + then + let + val excomm = fn comm => List.map (comm, fn (c, _) => c) + val comments1 = excomm comments1 + val comments2 = excomm comments2 + val comments3 = excomm comments3 + + val statements = + stmtMov::(comments1 @ (stmtAL::(comments2 @ comments3))) + val {statements, ...} + = LivenessBlock.toLivenessStatements + {statements = statements, live = liveOut2} + val statements + = List.fold (start, + List.concat [statements, finish], + op ::) + in + SOME (LivenessBlock.T + {entry = entry, + profileLabel = profileLabel, + statements = statements, + transfer = transfer}) + end + else NONE + | _ => Error.bug "amd64Simplify.PeepholeBlock: elimALRedundant" + + val (callback,elimALRedundant_msg) + = make_callback_msg "elimALRedundant" + in + val elimALRedundant : optimization + = {template = template, + rewriter = rewriter, + callback = callback} + val elimALRedundant_msg = elimALRedundant_msg + end + local val isInstructionSSEMOVS_dstTemp : statement_type -> bool = fn (Assembly.Instruction (Instruction.SSE_MOVS @@ -3936,6 +4102,13 @@ struct end local + val optimizations_pre + = elimALRedundant:: + nil + val optimizations_pre_msg + = elimALRedundant_msg:: + nil + val optimizations = elimALCopy:: elimSSEASCopy:: @@ -3968,6 +4141,21 @@ struct elimSSESSelfMove_minor_msg:: nil in + val peepholeLivenessBlock_pre + = fn block => (peepholeBlock {optimizations = optimizations_pre, + block = block}) + + val (peepholeLivenessBlock_pre, peepholeLivenessBlock_pre_msg) + = tracer + "peepholeLivenessBlock_pre" + peepholeLivenessBlock_pre + + val peepholeLivenessBlock_pre_msg + = fn () => (peepholeLivenessBlock_pre_msg (); + Control.indent (); + List.foreach(optimizations_pre_msg, fn msg => msg ()); + Control.unindent ()) + val peepholeLivenessBlock = fn block => (peepholeBlock {optimizations = optimizations, block = block}) @@ -4191,6 +4379,7 @@ struct {block = block, changed = false, msg = "peepholeBlock/moveHoist/peepholeLivenessBlock/copyPropagate"} + (***************************************************) (* peepholeBlock_pre *) (***************************************************) @@ -4219,9 +4408,30 @@ struct changed = false, msg = "amd64Liveness.LivenessBlock.toLivenessBlock"} + (***************************************************) + (* peepholeLivenessBlock_pre *) + (***************************************************) + val {block = block', + changed = changed'} + = PeepholeLivenessBlock.peepholeLivenessBlock_pre + block + + val _ = checkLivenessBlock + {block = block, + block' = block', + msg = "PeepholeLivenessBlock.peepholeLivenessBlock_pre"} + + val _ = changedLivenessBlock_msg + {block = block', + changed = changed', + msg = "PeepholeLivenessBlock.peepholeLivenessBlock_pre"} + val block = block' + val changed = changed orelse changed' + (***************************************************) (* moveHoist *) (***************************************************) + val {block = block', changed = changed'} = if !Control.Native.moveHoist @@ -4412,6 +4622,7 @@ struct amd64EntryTransfer.verifyEntryTransfer_msg (); PeepholeBlock.peepholeBlock_pre_msg (); amd64Liveness.LivenessBlock.toLivenessBlock_msg (); + PeepholeLivenessBlock.peepholeLivenessBlock_pre_msg (); MoveHoistLivenessBlock.moveHoist_msg (); PeepholeLivenessBlock.peepholeLivenessBlock_msg (); CopyPropagateLivenessBlock.copyPropagate_msg (); diff --git a/mlton/codegen/amd64-codegen/amd64.fun b/mlton/codegen/amd64-codegen/amd64.fun index e9422ff989..9dfe657ac0 100644 --- a/mlton/codegen/amd64-codegen/amd64.fun +++ b/mlton/codegen/amd64-codegen/amd64.fun @@ -3448,6 +3448,8 @@ struct NONE => "" | SOME f => FrameInfo.toString f] + val layout = Layout.str o toString + val uses_defs_kills = fn CReturn {dsts, func, ...} => let @@ -3673,6 +3675,8 @@ struct Option.toString Label.toString return, ">"] + val layout = Layout.str o toString + val uses_defs_kills = fn Switch {test, ...} => {uses = [test], defs = [], kills = []} @@ -3808,6 +3812,26 @@ struct else "NONE"); print "\n") + fun layout (T {entry, profileLabel, statements, transfer, ...}) + = let + open Layout + in + align [seq [Entry.layout entry, + str ": ", + record [("profileLabel", + Option.layout ProfileLabel.layout + profileLabel)], + str "\n"], + indent (align + [align (List.map (statements, + fn s => seq [Assembly.layout s, + str "\n"])), + Transfer.layout transfer], + 4)] + end + + fun layouts (block, output' : Layout.t -> unit) = output' (layout block) + val compress': t' list -> t' list = fn l => List.fold @@ -3865,5 +3889,8 @@ struct struct datatype t = T of {data: Assembly.t list, blocks: Block.t list} + + fun layouts (T {blocks, ...}, output: Layout.t -> unit) + = List.foreach (blocks, fn block => Block.layouts (block, output)) end end diff --git a/mlton/codegen/amd64-codegen/amd64.sig b/mlton/codegen/amd64-codegen/amd64.sig index 1f543c47a8..02b2620be1 100644 --- a/mlton/codegen/amd64-codegen/amd64.sig +++ b/mlton/codegen/amd64-codegen/amd64.sig @@ -1128,6 +1128,8 @@ signature AMD64 = transfer: Transfer.t} val printBlock : t -> unit + val layouts: t * (Layout.t -> unit) -> unit + val compress : t' list -> t list end @@ -1135,5 +1137,7 @@ signature AMD64 = sig datatype t = T of {data: Assembly.t list, blocks: Block.t list} + + val layouts: t * (Layout.t -> unit) -> unit end end diff --git a/mlton/codegen/c-codegen/c-codegen.fun b/mlton/codegen/c-codegen/c-codegen.fun index ba7ac0b1d7..c483a72bb9 100644 --- a/mlton/codegen/c-codegen/c-codegen.fun +++ b/mlton/codegen/c-codegen/c-codegen.fun @@ -207,6 +207,7 @@ fun implementsPrim (p: 'a Prim.t): bool = | Real_sub _ => true | Word_add _ => true | Word_addCheck _ => true + | Word_addCheckP _ => true | Word_andb _ => true | Word_castToReal _ => true | Word_equal _ => true @@ -215,8 +216,10 @@ fun implementsPrim (p: 'a Prim.t): bool = | Word_lt _ => true | Word_mul _ => true | Word_mulCheck _ => true + | Word_mulCheckP _ => true | Word_neg _ => true | Word_negCheck _ => true + | Word_negCheckP _ => true | Word_notb _ => true | Word_orb _ => true | Word_quot (_, {signed}) => not signed @@ -227,6 +230,7 @@ fun implementsPrim (p: 'a Prim.t): bool = | Word_rshift _ => true | Word_sub _ => true | Word_subCheck _ => true + | Word_subCheckP _ => true | Word_xorb _ => true | _ => false end diff --git a/mlton/codegen/llvm-codegen/llvm-codegen.fun b/mlton/codegen/llvm-codegen/llvm-codegen.fun index ee57bdc03b..c66dd78714 100644 --- a/mlton/codegen/llvm-codegen/llvm-codegen.fun +++ b/mlton/codegen/llvm-codegen/llvm-codegen.fun @@ -153,6 +153,7 @@ fun implementsPrim (p: 'a Prim.t): bool = | Thread_returnToC => false | Word_add _ => true | Word_addCheck _ => true + | Word_addCheckP _ => true | Word_andb _ => true | Word_castToReal _ => true | Word_equal _ => true @@ -170,8 +171,19 @@ fun implementsPrim (p: 'a Prim.t): bool = *) not (WordSize.equals (ws, WordSize.word64)) | _ => true) + | Word_mulCheckP (ws, _) => + (case (!Control.Target.arch, ws) of + (Control.Target.X86, ws) => + (* @llvm.smul.with.overflow.i64 becomes a call to __mulodi4. + * @llvm.umul.with.overflow.i64 becomes a call to __udivdi3. + * These are provided by compiler-rt and not always by libgcc. + * In any case, do not depend on non-standard libraries. + *) + not (WordSize.equals (ws, WordSize.word64)) + | _ => true) | Word_neg _ => true | Word_negCheck _ => true + | Word_negCheckP _ => true | Word_notb _ => true | Word_orb _ => true | Word_quot _ => true @@ -182,6 +194,7 @@ fun implementsPrim (p: 'a Prim.t): bool = | Word_rshift _ => true | Word_sub _ => true | Word_subCheck _ => true + | Word_subCheckP _ => true | Word_xorb _ => true | _ => false end @@ -624,6 +637,21 @@ and getOperandValue (cxt, operand) = fun outputPrim (prim, res, argty, arg0, arg1, arg2) = let datatype z = datatype Prim.Name.t + + fun mkoverflowp (ws, intrinsic) = + let + val tmp1 = nextLLVMReg () + val tmp2 = nextLLVMReg () + val ty = llws ws + val oper = concat ["\t", tmp1, " = call {", ty, ", i1} @llvm.", + intrinsic, ".with.overflow.", llwsInt ws, "(", ty, + " ", arg0, ", ", ty, " ", arg1, ")\n"] + val extr = concat ["\t", tmp2, " = extractvalue {", ty, ", i1} ", tmp1, + ", 1\n"] + val ext = mkconv (res, "zext", "i1", tmp2, "%Word32") + in + (concat [oper, extr, ext], "%Word32") + end in case Prim.name prim of CPointer_add => @@ -799,6 +827,8 @@ fun outputPrim (prim, res, argty, arg0, arg1, arg2) = in (inst, concat ["{", ty, ", i1}"]) end + | Word_addCheckP (ws, {signed}) => + mkoverflowp (ws, if signed then "sadd" else "uadd") | Word_andb ws => (mkinst (res, "and", llws ws, arg0, arg1), llws ws) | Word_castToReal (ws, rs) => (case rs of @@ -846,6 +876,8 @@ fun outputPrim (prim, res, argty, arg0, arg1, arg2) = in (inst, concat ["{", ty, ", i1}"]) end + | Word_mulCheckP (ws, {signed}) => + mkoverflowp (ws, if signed then "smul" else "umul") | Word_neg ws => (mkinst (res, "sub", llws ws, "0", arg0), llws ws) | Word_negCheck ws => let @@ -856,6 +888,20 @@ fun outputPrim (prim, res, argty, arg0, arg1, arg2) = in (inst, resTy) end + | Word_negCheckP ws => + let + val ty = llws ws + val tmp1 = nextLLVMReg () + val tmp2 = nextLLVMReg () + val oper = concat ["\t", tmp1, " = call {", ty, + ", i1} @llvm.ssub.with.overflow.", llwsInt ws, + "(", ty, " 0, ", ty, " ", arg0, ")\n"] + val extr = concat ["\t", tmp2 , " = extractvalue {", ty, ", i1}", + tmp1, ", 1\n"] + val ext = mkconv (res, "zext", "i1", tmp2, "%Word32") + in + (concat [oper, extr, ext], "%Word32") + end | Word_notb ws => (mkinst (res, "xor", llws ws, arg0, "-1"), llws ws) | Word_orb ws => (mkinst (res, "or", llws ws, arg0, arg1), llws ws) | Word_quot (ws, {signed}) => @@ -913,6 +959,8 @@ fun outputPrim (prim, res, argty, arg0, arg1, arg2) = in (inst, concat ["{", ty, ", i1}"]) end + | Word_subCheckP (ws, {signed}) => + mkoverflowp (ws, if signed then "ssub" else "usub") | Word_xorb ws => (mkinst (res, "xor", llws ws, arg0, arg1), llws ws) | _ => Error.bug "LLVM Codegen: Unsupported operation in outputPrim" end diff --git a/mlton/codegen/x86-codegen/x86-mlton-basic.fun b/mlton/codegen/x86-codegen/x86-mlton-basic.fun index d80bd298bd..63b480c8c4 100644 --- a/mlton/codegen/x86-codegen/x86-mlton-basic.fun +++ b/mlton/codegen/x86-codegen/x86-mlton-basic.fun @@ -190,6 +190,14 @@ struct val applyFFTempArgContentsOperand = Operand.memloc applyFFTempArgContents + val overflowCheckTemp = Label.fromString "overflowCheckTemp" + fun overflowCheckTempContents size + = makeContents {base = Immediate.label overflowCheckTemp, + size = size, + class = Classes.StaticTemp} + fun overflowCheckTempContentsOperand size + = Operand.memloc (overflowCheckTempContents size) + val realTemp1D = Label.fromString "realTemp1D" val realTemp1ContentsD = makeContents {base = Immediate.label realTemp1D, diff --git a/mlton/codegen/x86-codegen/x86-mlton-basic.sig b/mlton/codegen/x86-codegen/x86-mlton-basic.sig index 4f649f5b68..d163d3a7c0 100644 --- a/mlton/codegen/x86-codegen/x86-mlton-basic.sig +++ b/mlton/codegen/x86-codegen/x86-mlton-basic.sig @@ -88,6 +88,7 @@ signature X86_MLTON_BASIC = (* Static temps defined in x86-main.h *) val applyFFTempFunContentsOperand : x86.Operand.t val applyFFTempArgContentsOperand : x86.Operand.t + val overflowCheckTempContentsOperand : x86.Size.t -> x86.Operand.t val realTemp1ContentsOperand : x86.Size.t -> x86.Operand.t val realTemp2ContentsOperand : x86.Size.t -> x86.Operand.t val realTemp3ContentsOperand : x86.Size.t -> x86.Operand.t diff --git a/mlton/codegen/x86-codegen/x86-mlton.fun b/mlton/codegen/x86-codegen/x86-mlton.fun index b1829639f5..2da7051835 100644 --- a/mlton/codegen/x86-codegen/x86-mlton.fun +++ b/mlton/codegen/x86-codegen/x86-mlton.fun @@ -79,6 +79,7 @@ struct | Thread_returnToC => false | Word_add _ => true | Word_addCheck _ => true + | Word_addCheckP _ => true | Word_andb _ => true | Word_castToReal _ => false (* !! *) | Word_equal s => w32168 s @@ -87,8 +88,10 @@ struct | Word_lt (s, _) => w32168 s | Word_mul (s, _) => w32168 s | Word_mulCheck (s, _) => w32168 s + | Word_mulCheckP (s, _) => w32168 s | Word_neg _ => true | Word_negCheck _ => true + | Word_negCheckP _ => true | Word_notb _ => true | Word_orb _ => true | Word_quot (s, _) => w32168 s @@ -99,6 +102,7 @@ struct | Word_rshift (s, _) => w32168 s | Word_sub _ => true | Word_subCheck _ => true + | Word_subCheckP _ => true | Word_xorb _ => true | _ => false end @@ -246,6 +250,60 @@ struct transfer = NONE}] end + fun binalcc (oper, condition) + = let + val ((src1,src1size), + (src2,src2size)) = getSrc2 () + val (dst,dstsize) = getDst1 () + val tmp = overflowCheckTempContentsOperand src1size + val _ + = Assert.assert + ("x86MLton.prim: binal, src1size/src2size", + fn () => src1size = src2size) + + (* Reverse src1/src2 when src1 and src2 are temporaries + * and the oper is commutative. + *) + val (src1,src2) + = if (oper = Instruction.ADD) + orelse + (oper = Instruction.ADC) + orelse + (oper = Instruction.AND) + orelse + (oper = Instruction.OR) + orelse + (oper = Instruction.XOR) + then case (Operand.deMemloc src1, Operand.deMemloc src2) + of (SOME memloc_src1, SOME memloc_src2) + => if x86Liveness.track memloc_src1 + andalso + x86Liveness.track memloc_src2 + then (src2,src1) + else (src1,src2) + | _ => (src1,src2) + else (src1,src2) + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp, + src = src1, + size = src1size}, + Assembly.instruction_binal + {oper = oper, + dst = tmp, + src = src2, + size = src1size}, + Assembly.instruction_setcc + {condition = condition, + dst = dst, + size = dstsize}], + transfer = NONE}] + end + fun binal64 (oper1, oper2) = let val ((src1,src1size), @@ -306,6 +364,50 @@ struct transfer = NONE}] end + fun binal64cc (oper1, oper2, condition) + = let + val ((src1,src1size), + (src2,src2size), + (src3,src3size), + (src4,src4size)) = getSrc4 () + val (dst,dstsize) = getDst1 () + val tmp1 = overflowCheckTempContentsOperand src1size + val tmp2 = wordTemp1ContentsOperand src2size + val _ + = Assert.assert + ("x86MLton.prim: binal64cc, src1size/src2size/src3size/src4size", + fn () => src1size = src3size andalso + src2size = src4size) + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp1, + src = src1, + size = src1size}, + Assembly.instruction_mov + {dst = tmp2, + src = src2, + size = src2size}, + Assembly.instruction_binal + {oper = oper1, + dst = tmp1, + src = src3, + size = src1size}, + Assembly.instruction_binal + {oper = oper2, + dst = tmp2, + src = src4, + size = src2size}, + Assembly.instruction_setcc + {condition = condition, + dst = dst, + size = dstsize}], + transfer = NONE}] + end + fun pmd oper = let val ((src1,src1size), @@ -350,6 +452,55 @@ struct transfer = NONE}] end + fun pmdcc (oper, condition) + = let + val ((src1,src1size), + (src2,src2size)) = getSrc2 () + val (dst,dstsize) = getDst1 () + val tmp = overflowCheckTempContentsOperand src1size + val _ + = Assert.assert + ("x86MLton.prim: pmdcc, src1size/src2size", + fn () => src1size = src2size) + + (* Reverse src1/src2 when src1 and src2 are temporaries + * and the oper is commutative. + *) + val (src1,src2) + = if (oper = Instruction.IMUL) + orelse + (oper = Instruction.MUL) + then case (Operand.deMemloc src1, Operand.deMemloc src2) + of (SOME memloc_src1, SOME memloc_src2) + => if x86Liveness.track memloc_src1 + andalso + x86Liveness.track memloc_src2 + then (src2,src1) + else (src1,src2) + | _ => (src1,src2) + else (src1,src2) + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp, + src = src1, + size = src1size}, + Assembly.instruction_pmd + {oper = oper, + dst = tmp, + src = src2, + size = src1size}, + Assembly.instruction_setcc + {condition = condition, + dst = dst, + size = dstsize}], + transfer = NONE}] + end + + fun imul2 () = let val ((src1,src1size), @@ -389,6 +540,116 @@ struct transfer = NONE}] end + fun imul2cc condition + = let + val ((src1,src1size), + (src2,src2size)) = getSrc2 () + val (dst,dstsize) = getDst1 () + val tmp = overflowCheckTempContentsOperand src1size + val _ + = Assert.assert + ("x86MLton.prim: imul2, src1size/src2size", + fn () => src1size = src2size) + + (* Reverse src1/src2 when src1 and src2 are temporaries + * and the oper is commutative. + *) + val (src1,src2) + = case (Operand.deMemloc src1, Operand.deMemloc src2) + of (SOME memloc_src1, SOME memloc_src2) + => if x86Liveness.track memloc_src1 + andalso + x86Liveness.track memloc_src2 + then (src2,src1) + else (src1,src2) + | _ => (src1,src2) + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp, + src = src1, + size = src1size}, + Assembly.instruction_imul2 + {dst = tmp, + src = src2, + size = src1size}, + Assembly.instruction_setcc + {condition = condition, + dst = dst, + size = dstsize}], + transfer = NONE}] + end + + fun negcc () + = let + val (src,srcsize) = getSrc1 () + val (dst,dstsize) = getDst1 () + val tmp = overflowCheckTempContentsOperand srcsize + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp, + src = Operand.immediate_zero, + size = srcsize}, + Assembly.instruction_binal + {oper = Instruction.SUB, + dst = tmp, + src = src, + size = srcsize}, + Assembly.instruction_setcc + {condition = Instruction.O, + dst = dst, + size = dstsize}], + transfer = NONE}] + end + + fun neg64cc () + = let + val ((src1,src1size), + (src2,src2size)) = getSrc2 () + val (dst,dstsize) = getDst1 () + val _ + = Assert.assert + ("x86MLton.prim: neg64cc, src1size/src2size", + fn () => src1size = src2size) + val tmp1 = overflowCheckTempContentsOperand src1size + val tmp2 = wordTemp1ContentsOperand src2size + in + AppendList.fromList + [Block.mkBlock' + {entry = NONE, + statements + = [Assembly.instruction_mov + {dst = tmp1, + src = Operand.immediate_zero, + size = src1size}, + Assembly.instruction_mov + {dst = tmp2, + src = Operand.immediate_zero, + size = src2size}, + Assembly.instruction_binal + {oper = Instruction.SUB, + dst = tmp1, + src = src1, + size = src1size}, + Assembly.instruction_binal + {oper = Instruction.SBB, + dst = tmp2, + src = src2, + size = src2size}, + Assembly.instruction_setcc + {condition = Instruction.O, + dst = dst, + size = dstsize}], + transfer = NONE}] + end + fun unal oper = let val (src,srcsize) = getSrc1 () @@ -665,6 +926,9 @@ struct | W16 => sral i | W32 => sral i | W64 => Error.bug "x86MLton.prim: shift, W64" + + fun flag {signed} = + if signed then x86.Instruction.O else x86.Instruction.C in AppendList.appends [comment_begin, @@ -1301,6 +1565,16 @@ struct | W16 => binal Instruction.ADD | W32 => binal Instruction.ADD | W64 => binal64 (Instruction.ADD, Instruction.ADC)) + | Word_addCheckP (s, sg) => + let + val cond = flag sg + in + case WordSize.prim s of + W8 => binalcc (Instruction.ADD, cond) + | W16 => binalcc (Instruction.ADD, cond) + | W32 => binalcc (Instruction.ADD, cond) + | W64 => binal64cc (Instruction.ADD, Instruction.ADC, cond) + end | Word_andb s => bitop (s, Instruction.AND) | Word_equal _ => cmp Instruction.E | Word_lshift s => shift (s, Instruction.SHL) @@ -1313,6 +1587,20 @@ struct | W16 => imul2 () | W32 => imul2 () | W64 => Error.bug "x86MLton.prim: Word_mul, W64") + | Word_mulCheckP (s, {signed}) => + if signed + then + (case WordSize.prim s of + W8 => pmdcc (x86.Instruction.IMUL, x86.Instruction.O) + | W16 => imul2cc x86.Instruction.O + | W32 => imul2cc x86.Instruction.O + | W64 => Error.bug "x86MLton.arith: Word_mulCheckP, W64") + else + (case WordSize.prim s of + W8 => pmdcc (x86.Instruction.MUL, x86.Instruction.C) + | W16 => pmdcc (x86.Instruction.MUL, x86.Instruction.C) + | W32 => pmdcc (x86.Instruction.MUL, x86.Instruction.C) + | W64 => Error.bug "x86MLton.arith: Word_mulCheckP, W64") | Word_neg s => (case WordSize.prim s of W8 => unal Instruction.NEG @@ -1324,6 +1612,12 @@ struct oper = Instruction.ADC, src = Operand.immediate_zero, size = dstsize}])) + | Word_negCheckP s => + (case WordSize.prim s of + W8 => negcc () + | W16 => negcc () + | W32 => negcc () + | W64 => neg64cc ()) | Word_notb s => (case WordSize.prim s of W8 => unal Instruction.NOT @@ -1345,6 +1639,16 @@ struct | W16 => binal Instruction.SUB | W32 => binal Instruction.SUB | W64 => binal64 (Instruction.SUB, Instruction.SBB)) + | Word_subCheckP (s, sg) => + let + val cond = flag sg + in + case WordSize.prim s of + W8 => binalcc (Instruction.SUB, cond) + | W16 => binalcc (Instruction.SUB, cond) + | W32 => binalcc (Instruction.SUB, cond) + | W64 => binal64cc (Instruction.SUB, Instruction.SBB, cond) + end | Word_rndToReal (s, s', _) => let fun default () = diff --git a/mlton/codegen/x86-codegen/x86-simplify.fun b/mlton/codegen/x86-codegen/x86-simplify.fun index acb6662ab3..5336db5293 100644 --- a/mlton/codegen/x86-codegen/x86-simplify.fun +++ b/mlton/codegen/x86-codegen/x86-simplify.fun @@ -655,6 +655,9 @@ struct (Instruction.BinAL {oper = Instruction.SBB, ...}) => (true, if b then b' else true) + | Assembly.Instruction + (Instruction.MOV _) + => (b, b') | Assembly.Instruction (Instruction.SETcc {condition = Instruction.C, ...}) @@ -1608,7 +1611,7 @@ struct (* elimBinAL0L:: *) (* elimBinAL0R:: *) elimAddSub1:: - elimMDPow2:: +(* elimMDPow2:: *) elimCMPTEST:: nil val optimizations_pre_msg @@ -1616,18 +1619,20 @@ struct (* elimBinAL0L_msg:: *) (* elimBinAL0R_msg:: *) elimAddSub1_msg:: - elimMDPow2_msg:: +(* elimMDPow2_msg:: *) nil val optimizations_post - = elimBinALMDDouble:: + = elimMDPow2:: + elimBinALMDDouble:: elimFltBinADouble:: elimCMPTEST:: elimCMP0:: elimALTEST:: nil val optimizations_post_msg - = elimBinALMDDouble_msg:: + = elimMDPow2_msg:: + elimBinALMDDouble_msg:: elimFltBinADouble_msg:: elimCMPTEST_msg:: elimCMP0_msg:: @@ -2939,6 +2944,15 @@ struct (finish, (false, false), fn ((asm, _), (b, b')) => case asm of Assembly.Comment _ => (b, b') + | Assembly.Instruction + (Instruction.BinAL {oper = Instruction.ADC, ...}) + => (true, if b then b' else true) + | Assembly.Instruction + (Instruction.BinAL {oper = Instruction.SBB, ...}) + => (true, if b then b' else true) + | Assembly.Instruction + (Instruction.MOV _) + => (b, b') | Assembly.Instruction (Instruction.SETcc _) => (true, if b then b' else true) @@ -3181,6 +3195,154 @@ struct val elimALCopy_msg = elimALCopy_msg end + local + fun isInstructionMOV_aux (check) : statement_type -> bool + = fn (Assembly.Instruction (Instruction.MOV + {dst = Operand.MemLoc memloc,...}), + _) + => check memloc + | _ => false + + val isInstructionMOV = isInstructionMOV_aux (fn _ => true) + val isInstructionMOV_dstTemp = isInstructionMOV_aux x86Liveness.track + + fun isInstructionAL_aux (check) : statement_type -> bool + = fn (Assembly.Instruction (Instruction.BinAL + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | (Assembly.Instruction (Instruction.pMD + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | (Assembly.Instruction (Instruction.IMUL2 + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | (Assembly.Instruction (Instruction.UnAL + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | (Assembly.Instruction (Instruction.SRAL + {dst = Operand.MemLoc memloc,...}), _) + => check memloc + | _ => false + val isInstructionAL = isInstructionAL_aux (fn _ => true) + fun isDeadTemp dead memloc + = x86Liveness.track memloc andalso LiveSet.contains (dead, memloc) + val isInstructionAL_dstDeadTemp : statement_type -> bool + = fn (instr, liveness as Liveness.T {dead, ...}) + => isInstructionAL_aux (isDeadTemp dead) (instr, liveness) + + val template : template + = {start = EmptyOrNonEmpty, + statements = [One isInstructionMOV, + All isComment, + One isInstructionAL, + All isComment, + One isInstructionMOV_dstTemp, + All isComment, + One isInstructionAL_dstDeadTemp], + finish = EmptyOrNonEmpty, + transfer = fn _ => true} + + val rewriter : rewriter + = fn {entry, + profileLabel, + start, + statements = + [[(stmtMov as Assembly.Instruction (Instruction.MOV + {src = src1x, + dst = dst1z, ...}), + _)], + comments1, + [(stmtAL as Assembly.Instruction instrAL1, _)], + comments2, + [(Assembly.Instruction (Instruction.MOV + {src = src2x, + dst = dst2z, ...}), + _)], + comments3, + [(Assembly.Instruction instrAL2, + Liveness.T {liveOut = liveOut2, ...})]], + finish, + transfer} + => if !Control.Native.elimALRedundant andalso + Operand.eq (src1x, src2x) andalso + (let + fun checkUn (oper1, dst1, oper2, dst2) + = oper1 = oper2 andalso + Operand.eq(dst1z, dst1) andalso + Operand.eq(dst2z, dst2) + + fun checkBin (oper1, src1, dst1, oper2, src2, dst2) + = oper1 = oper2 andalso + Operand.eq(src1, src2) andalso + Operand.eq(dst1z, dst1) andalso + Operand.eq(dst2z, dst2) + + in + case (instrAL1, instrAL2) of + (Instruction.BinAL + {oper = oper1, src = src1, dst = dst1, ...}, + Instruction.BinAL + {oper = oper2, src = src2, dst = dst2, ...}) + => checkBin (oper1, src1, dst1, oper2, src2, dst2) + | (Instruction.pMD + {oper = oper1, src = src1, dst = dst1, ...}, + Instruction.pMD + {oper = oper2, src = src2, dst = dst2, ...}) + => checkBin (oper1, src1, dst1, oper2, src2, dst2) + | (Instruction.IMUL2 + {src = src1, dst = dst1, ...}, + Instruction.IMUL2 + {src = src2, dst = dst2, ...}) + => checkBin (Instruction.IMUL, src1, dst1, + Instruction.IMUL, src2, dst2) + | (Instruction.UnAL + {oper = oper1, dst = dst1, ...}, + Instruction.UnAL + {oper = oper2, dst = dst2, ...}) + => checkUn (oper1, dst1, oper2, dst2) + | (Instruction.SRAL + {oper = oper1, count = src1, dst = dst1, ...}, + Instruction.SRAL + {oper = oper2, count = src2, dst = dst2, ...}) + => checkBin (oper1, src1, dst1, oper2, src2, dst2) + | _ => false + end) + then + let + val excomm = fn comm => List.map (comm, fn (c, _) => c) + val comments1 = excomm comments1 + val comments2 = excomm comments2 + val comments3 = excomm comments3 + + val statements = + stmtMov::(comments1 @ (stmtAL::(comments2 @ comments3))) + val {statements, ...} + = LivenessBlock.toLivenessStatements + {statements = statements, live = liveOut2} + val statements + = List.fold (start, + List.concat [statements, finish], + op ::) + in + SOME (LivenessBlock.T + {entry = entry, + profileLabel = profileLabel, + statements = statements, + transfer = transfer}) + end + else NONE + | _ => Error.bug "x86Simplify.PeepholeBlock: elimALRedundant" + + val (callback,elimALRedundant_msg) + = make_callback_msg "elimALRedundant" + in + val elimALRedundant : optimization + = {template = template, + rewriter = rewriter, + callback = callback} + val elimALRedundant_msg = elimALRedundant_msg + end + local val isInstructionMOV_eqSrcDst : statement_type -> bool = fn (Assembly.Instruction (Instruction.MOV @@ -4065,6 +4227,13 @@ struct end local + val optimizations_pre + = elimALRedundant:: + nil + val optimizations_pre_msg + = elimALRedundant_msg:: + nil + val optimizations = elimALCopy:: elimFltACopy:: @@ -4097,6 +4266,21 @@ struct elimFltSelfMove_minor_msg:: nil in + val peepholeLivenessBlock_pre + = fn block => (peepholeBlock {optimizations = optimizations_pre, + block = block}) + + val (peepholeLivenessBlock_pre, peepholeLivenessBlock_pre_msg) + = tracer + "peepholeLivenessBlock_pre" + peepholeLivenessBlock_pre + + val peepholeLivenessBlock_pre_msg + = fn () => (peepholeLivenessBlock_pre_msg (); + Control.indent (); + List.foreach(optimizations_pre_msg, fn msg => msg ()); + Control.unindent ()) + val peepholeLivenessBlock = fn block => (peepholeBlock {optimizations = optimizations, block = block}) @@ -4348,6 +4532,26 @@ struct changed = false, msg = "x86Liveness.LivenessBlock.toLivenessBlock"} + (***************************************************) + (* peepholeLivenessBlock_pre *) + (***************************************************) + val {block = block', + changed = changed'} + = PeepholeLivenessBlock.peepholeLivenessBlock_pre + block + + val _ = checkLivenessBlock + {block = block, + block' = block', + msg = "PeepholeLivenessBlock.peepholeLivenessBlock_pre"} + + val _ = changedLivenessBlock_msg + {block = block', + changed = changed', + msg = "PeepholeLivenessBlock.peepholeLivenessBlock_pre"} + val block = block' + val changed = changed orelse changed' + (***************************************************) (* moveHoist *) (***************************************************) @@ -4541,6 +4745,7 @@ struct x86EntryTransfer.verifyEntryTransfer_msg (); PeepholeBlock.peepholeBlock_pre_msg (); x86Liveness.LivenessBlock.toLivenessBlock_msg (); + PeepholeLivenessBlock.peepholeLivenessBlock_pre_msg (); MoveHoistLivenessBlock.moveHoist_msg (); PeepholeLivenessBlock.peepholeLivenessBlock_msg (); CopyPropagateLivenessBlock.copyPropagate_msg (); diff --git a/mlton/control/control-flags.sig b/mlton/control/control-flags.sig index 8e577cab50..49c28cfc74 100644 --- a/mlton/control/control-flags.sig +++ b/mlton/control/control-flags.sig @@ -270,6 +270,9 @@ signature CONTROL_FLAGS = (* whether or not to use comments in native codegen *) val commented: int ref + (* whether to eliminate redundant AL ops in native codegen *) + val elimALRedundant: bool ref + (* whether or not to track liveness of stack slots *) val liveStack: bool ref diff --git a/mlton/control/control-flags.sml b/mlton/control/control-flags.sml index 8f1b425207..73cc05373a 100644 --- a/mlton/control/control-flags.sml +++ b/mlton/control/control-flags.sml @@ -946,6 +946,10 @@ structure Native = default = 0, toString = Int.toString} + val elimALRedundant = control {name = "elim AL redundant", + default = true, + toString = Bool.toString} + val liveStack = control {name = "native live stack", default = false, toString = Bool.toString} diff --git a/mlton/main/main.fun b/mlton/main/main.fun index 4d03b7a9dc..14eec66823 100644 --- a/mlton/main/main.fun +++ b/mlton/main/main.fun @@ -602,6 +602,9 @@ fun makeOptions {usage} = | SOME v => v])), (Expert, "native-commented", " ", "level of comments (0)", intRef Native.commented), + (Expert, "native-al-redundant", "{true|false}", + "eliminate redundant AL ops", + boolRef Native.elimALRedundant), (Expert, "native-copy-prop", " {true|false}", "use copy propagation", boolRef Native.copyProp), diff --git a/mlton/ssa/redundant-tests.fun b/mlton/ssa/redundant-tests.fun index 773834ff0f..b310e0fd3e 100644 --- a/mlton/ssa/redundant-tests.fun +++ b/mlton/ssa/redundant-tests.fun @@ -147,8 +147,8 @@ fun transform (Program.T {globals, datatypes, functions, main}) = exp = ConApp {con = c, args = Vector.new0 ()}}) end in - val (trueVar, t) = make Con.truee - val (falseVar, f) = make Con.falsee + val (trueVar, trueStmt) = make Con.truee + val (falseVar, falseStmt) = make Con.falsee end local val statements = ref [] @@ -169,7 +169,8 @@ fun transform (Program.T {globals, datatypes, functions, main}) = end) val ones = Vector.fromList (!statements) end - val globals = Vector.concat [Vector.new2 (t, f), ones, globals] + val globals = Vector.concat [Vector.new2 (trueStmt, falseStmt), ones, + globals] val shrink = shrinkFunction {globals = globals} val numSimplified = ref 0 fun simplifyFunction f = @@ -324,9 +325,43 @@ fun transform (Program.T {globals, datatypes, functions, main}) = Vector.map (blocks, fn Block.T {label, args, statements, transfer} => let + fun add1Eligible (x: Var.t, s: WordSize.t, sg) = + isFact (label, fn Fact.T {lhs, rel, rhs} => + case (lhs, rel, rhs) of + (Oper.Var x', Rel.LT sg', _) => + Var.equals (x, x') + andalso sg = sg' + | (Oper.Var x', Rel.LE sg', + Oper.Const c) => + Var.equals (x, x') + andalso sg = sg' + andalso + (case c of + Const.Word w => + WordX.lt + (w, WordX.max (s, sg), sg) + | _ => Error.bug "RedundantTests.add1: strange fact") + | _ => false) + fun sub1Eligible (x: Var.t, s: WordSize.t, sg) = + isFact (label, fn Fact.T {lhs, rel, rhs} => + case (lhs, rel, rhs) of + (_, Rel.LT sg', Oper.Var x') => + Var.equals (x, x') + andalso sg = sg' + | (Oper.Const c, Rel.LE sg', + Oper.Var x') => + Var.equals (x, x') + andalso sg = sg' + andalso + (case c of + Const.Word w => + WordX.gt + (w, WordX.min (s, sg), sg) + | _ => Error.bug "RedundantTests.sub1: strange fact") + | _ => false) val statements = Vector.map - (statements, fn statement as Statement.T {ty, var, ...} => + (statements, fn statement as Statement.T {ty, var, exp, ...} => let fun doit x = (Int.inc numSimplified @@ -342,6 +377,62 @@ fun transform (Program.T {globals, datatypes, functions, main}) = exp = Var x}) fun falsee () = doit falseVar fun truee () = doit trueVar + + fun checkPrimApp (args, prim) = + let + open Prim.Name + + fun add1 (x: Var.t, s: WordSize.t, sg) = + if add1Eligible (x, s, sg) then falsee () + else statement + fun sub1 (x: Var.t, s: WordSize.t, sg) = + if sub1Eligible (x, s, sg) then falsee () + else statement + + fun add (c: Const.t, x: Var.t, + (s, sg as {signed})) = + case c of + Const.Word i => + if WordX.isOne i + then add1 (x, s, sg) + else if signed andalso WordX.isNegOne i + then sub1 (x, s, sg) + else statement + | _ => Error.bug ("RedundantTests.add: strange const") + in + case Prim.name prim of + Word_addCheckP s => + let + val x1 = Vector.sub (args, 0) + val x2 = Vector.sub (args, 1) + in + case varInfo x1 of + Const c => add (c, x2, s) + | _ => (case varInfo x2 of + Const c => add (c, x1, s) + | _ => statement) + end + | Word_subCheckP (s, sg as {signed}) => + let + val x1 = Vector.sub (args, 0) + val x2 = Vector.sub (args, 1) + in + case varInfo x2 of + Const c => + (case c of + Const.Word i => + if WordX.isOne i + then sub1 (x1, s, sg) + else if signed andalso + WordX.isNegOne i + then + add1 (x1, s, sg) + else statement + | _ => Error.bug ("RedundantTests.sub: strange const")) + | _ => statement + end + | _ => statement + end in case var of NONE => statement @@ -361,7 +452,10 @@ fun transform (Program.T {globals, datatypes, functions, main}) = False => falsee () | True => truee () | Unknown => statement) - | _ => statement) + | _ => (case exp of + Exp.PrimApp {args, prim, ...} => + checkPrimApp (args, prim) + | _ => statement)) end) val noChange = (statements, transfer) fun arith (args: Var.t vector, @@ -388,42 +482,12 @@ fun transform (Program.T {globals, datatypes, functions, main}) = dst = success}) end fun add1 (x: Var.t, s: WordSize.t, sg) = - if isFact (label, fn Fact.T {lhs, rel, rhs} => - case (lhs, rel, rhs) of - (Oper.Var x', Rel.LT sg', _) => - Var.equals (x, x') - andalso sg = sg' - | (Oper.Var x', Rel.LE sg', - Oper.Const c) => - Var.equals (x, x') - andalso sg = sg' - andalso - (case c of - Const.Word w => - WordX.lt - (w, WordX.max (s, sg), sg) - | _ => Error.bug "RedundantTests.add1: strange fact") - | _ => false) - then simplify (Prim.wordAdd s, x, s) + if add1Eligible (x, s, sg) + then simplify (Prim.wordAdd s, x, s) else noChange fun sub1 (x: Var.t, s: WordSize.t, sg) = - if isFact (label, fn Fact.T {lhs, rel, rhs} => - case (lhs, rel, rhs) of - (_, Rel.LT sg', Oper.Var x') => - Var.equals (x, x') - andalso sg = sg' - | (Oper.Const c, Rel.LE sg', - Oper.Var x') => - Var.equals (x, x') - andalso sg = sg' - andalso - (case c of - Const.Word w => - WordX.gt - (w, WordX.min (s, sg), sg) - | _ => Error.bug "RedundantTests.sub1: strange fact") - | _ => false) - then simplify (Prim.wordSub s, x, s) + if sub1Eligible (x, s, sg) + then simplify (Prim.wordSub s, x, s) else noChange fun add (c: Const.t, x: Var.t, (s, sg as {signed})) = case c of diff --git a/regression/int-mul-pow2.ok b/regression/int-mul-pow2.ok new file mode 100644 index 0000000000..31e4890b66 --- /dev/null +++ b/regression/int-mul-pow2.ok @@ -0,0 +1,3440 @@ +~32 * 64 = Overflow +~32 * 32 = Overflow +~32 * 16 = Overflow +~32 * 8 = Overflow +~32 * 4 = ~128 +~31 * 64 = Overflow +~31 * 32 = Overflow +~31 * 16 = Overflow +~31 * 8 = Overflow +~31 * 4 = ~124 +~30 * 64 = Overflow +~30 * 32 = Overflow +~30 * 16 = Overflow +~30 * 8 = Overflow +~30 * 4 = ~120 +~29 * 64 = Overflow +~29 * 32 = Overflow +~29 * 16 = Overflow +~29 * 8 = Overflow +~29 * 4 = ~116 +~28 * 64 = Overflow +~28 * 32 = Overflow +~28 * 16 = Overflow +~28 * 8 = Overflow +~28 * 4 = ~112 +~27 * 64 = Overflow +~27 * 32 = Overflow +~27 * 16 = Overflow +~27 * 8 = Overflow +~27 * 4 = ~108 +~26 * 64 = Overflow +~26 * 32 = Overflow +~26 * 16 = Overflow +~26 * 8 = Overflow +~26 * 4 = ~104 +~25 * 64 = Overflow +~25 * 32 = Overflow +~25 * 16 = Overflow +~25 * 8 = Overflow +~25 * 4 = ~100 +~24 * 64 = Overflow +~24 * 32 = Overflow +~24 * 16 = Overflow +~24 * 8 = Overflow +~24 * 4 = ~96 +~23 * 64 = Overflow +~23 * 32 = Overflow +~23 * 16 = Overflow +~23 * 8 = Overflow +~23 * 4 = ~92 +~22 * 64 = Overflow +~22 * 32 = Overflow +~22 * 16 = Overflow +~22 * 8 = Overflow +~22 * 4 = ~88 +~21 * 64 = Overflow +~21 * 32 = Overflow +~21 * 16 = Overflow +~21 * 8 = Overflow +~21 * 4 = ~84 +~20 * 64 = Overflow +~20 * 32 = Overflow +~20 * 16 = Overflow +~20 * 8 = Overflow +~20 * 4 = ~80 +~19 * 64 = Overflow +~19 * 32 = Overflow +~19 * 16 = Overflow +~19 * 8 = Overflow +~19 * 4 = ~76 +~18 * 64 = Overflow +~18 * 32 = Overflow +~18 * 16 = Overflow +~18 * 8 = Overflow +~18 * 4 = ~72 +~17 * 64 = Overflow +~17 * 32 = Overflow +~17 * 16 = Overflow +~17 * 8 = Overflow +~17 * 4 = ~68 +~16 * 64 = Overflow +~16 * 32 = Overflow +~16 * 16 = Overflow +~16 * 8 = ~128 +~16 * 4 = ~64 +~15 * 64 = Overflow +~15 * 32 = Overflow +~15 * 16 = Overflow +~15 * 8 = ~120 +~15 * 4 = ~60 +~14 * 64 = Overflow +~14 * 32 = Overflow +~14 * 16 = Overflow +~14 * 8 = ~112 +~14 * 4 = ~56 +~13 * 64 = Overflow +~13 * 32 = Overflow +~13 * 16 = Overflow +~13 * 8 = ~104 +~13 * 4 = ~52 +~12 * 64 = Overflow +~12 * 32 = Overflow +~12 * 16 = Overflow +~12 * 8 = ~96 +~12 * 4 = ~48 +~11 * 64 = Overflow +~11 * 32 = Overflow +~11 * 16 = Overflow +~11 * 8 = ~88 +~11 * 4 = ~44 +~10 * 64 = Overflow +~10 * 32 = Overflow +~10 * 16 = Overflow +~10 * 8 = ~80 +~10 * 4 = ~40 +~9 * 64 = Overflow +~9 * 32 = Overflow +~9 * 16 = Overflow +~9 * 8 = ~72 +~9 * 4 = ~36 +~8 * 64 = Overflow +~8 * 32 = Overflow +~8 * 16 = ~128 +~8 * 8 = ~64 +~8 * 4 = ~32 +~7 * 64 = Overflow +~7 * 32 = Overflow +~7 * 16 = ~112 +~7 * 8 = ~56 +~7 * 4 = ~28 +~6 * 64 = Overflow +~6 * 32 = Overflow +~6 * 16 = ~96 +~6 * 8 = ~48 +~6 * 4 = ~24 +~5 * 64 = Overflow +~5 * 32 = Overflow +~5 * 16 = ~80 +~5 * 8 = ~40 +~5 * 4 = ~20 +~4 * 64 = Overflow +~4 * 32 = ~128 +~4 * 16 = ~64 +~4 * 8 = ~32 +~4 * 4 = ~16 +~3 * 64 = Overflow +~3 * 32 = ~96 +~3 * 16 = ~48 +~3 * 8 = ~24 +~3 * 4 = ~12 +~2 * 64 = ~128 +~2 * 32 = ~64 +~2 * 16 = ~32 +~2 * 8 = ~16 +~2 * 4 = ~8 +~1 * 64 = ~64 +~1 * 32 = ~32 +~1 * 16 = ~16 +~1 * 8 = ~8 +~1 * 4 = ~4 +0 * 64 = 0 +0 * 32 = 0 +0 * 16 = 0 +0 * 8 = 0 +0 * 4 = 0 +1 * 64 = 64 +1 * 32 = 32 +1 * 16 = 16 +1 * 8 = 8 +1 * 4 = 4 +2 * 64 = Overflow +2 * 32 = 64 +2 * 16 = 32 +2 * 8 = 16 +2 * 4 = 8 +3 * 64 = Overflow +3 * 32 = 96 +3 * 16 = 48 +3 * 8 = 24 +3 * 4 = 12 +4 * 64 = Overflow +4 * 32 = Overflow +4 * 16 = 64 +4 * 8 = 32 +4 * 4 = 16 +5 * 64 = Overflow +5 * 32 = Overflow +5 * 16 = 80 +5 * 8 = 40 +5 * 4 = 20 +6 * 64 = Overflow +6 * 32 = Overflow +6 * 16 = 96 +6 * 8 = 48 +6 * 4 = 24 +7 * 64 = Overflow +7 * 32 = Overflow +7 * 16 = 112 +7 * 8 = 56 +7 * 4 = 28 +8 * 64 = Overflow +8 * 32 = Overflow +8 * 16 = Overflow +8 * 8 = 64 +8 * 4 = 32 +9 * 64 = Overflow +9 * 32 = Overflow +9 * 16 = Overflow +9 * 8 = 72 +9 * 4 = 36 +10 * 64 = Overflow +10 * 32 = Overflow +10 * 16 = Overflow +10 * 8 = 80 +10 * 4 = 40 +11 * 64 = Overflow +11 * 32 = Overflow +11 * 16 = Overflow +11 * 8 = 88 +11 * 4 = 44 +12 * 64 = Overflow +12 * 32 = Overflow +12 * 16 = Overflow +12 * 8 = 96 +12 * 4 = 48 +13 * 64 = Overflow +13 * 32 = Overflow +13 * 16 = Overflow +13 * 8 = 104 +13 * 4 = 52 +14 * 64 = Overflow +14 * 32 = Overflow +14 * 16 = Overflow +14 * 8 = 112 +14 * 4 = 56 +15 * 64 = Overflow +15 * 32 = Overflow +15 * 16 = Overflow +15 * 8 = 120 +15 * 4 = 60 +16 * 64 = Overflow +16 * 32 = Overflow +16 * 16 = Overflow +16 * 8 = Overflow +16 * 4 = 64 +17 * 64 = Overflow +17 * 32 = Overflow +17 * 16 = Overflow +17 * 8 = Overflow +17 * 4 = 68 +18 * 64 = Overflow +18 * 32 = Overflow +18 * 16 = Overflow +18 * 8 = Overflow +18 * 4 = 72 +19 * 64 = Overflow +19 * 32 = Overflow +19 * 16 = Overflow +19 * 8 = Overflow +19 * 4 = 76 +20 * 64 = Overflow +20 * 32 = Overflow +20 * 16 = Overflow +20 * 8 = Overflow +20 * 4 = 80 +21 * 64 = Overflow +21 * 32 = Overflow +21 * 16 = Overflow +21 * 8 = Overflow +21 * 4 = 84 +22 * 64 = Overflow +22 * 32 = Overflow +22 * 16 = Overflow +22 * 8 = Overflow +22 * 4 = 88 +23 * 64 = Overflow +23 * 32 = Overflow +23 * 16 = Overflow +23 * 8 = Overflow +23 * 4 = 92 +24 * 64 = Overflow +24 * 32 = Overflow +24 * 16 = Overflow +24 * 8 = Overflow +24 * 4 = 96 +25 * 64 = Overflow +25 * 32 = Overflow +25 * 16 = Overflow +25 * 8 = Overflow +25 * 4 = 100 +26 * 64 = Overflow +26 * 32 = Overflow +26 * 16 = Overflow +26 * 8 = Overflow +26 * 4 = 104 +27 * 64 = Overflow +27 * 32 = Overflow +27 * 16 = Overflow +27 * 8 = Overflow +27 * 4 = 108 +28 * 64 = Overflow +28 * 32 = Overflow +28 * 16 = Overflow +28 * 8 = Overflow +28 * 4 = 112 +29 * 64 = Overflow +29 * 32 = Overflow +29 * 16 = Overflow +29 * 8 = Overflow +29 * 4 = 116 +30 * 64 = Overflow +30 * 32 = Overflow +30 * 16 = Overflow +30 * 8 = Overflow +30 * 4 = 120 +31 * 64 = Overflow +31 * 32 = Overflow +31 * 16 = Overflow +31 * 8 = Overflow +31 * 4 = 124 +32 * 64 = Overflow +32 * 32 = Overflow +32 * 16 = Overflow +32 * 8 = Overflow +32 * 4 = Overflow +~32 * ~128 = Overflow +~32 * ~64 = Overflow +~32 * ~32 = Overflow +~32 * ~16 = Overflow +~32 * ~8 = Overflow +~31 * ~128 = Overflow +~31 * ~64 = Overflow +~31 * ~32 = Overflow +~31 * ~16 = Overflow +~31 * ~8 = Overflow +~30 * ~128 = Overflow +~30 * ~64 = Overflow +~30 * ~32 = Overflow +~30 * ~16 = Overflow +~30 * ~8 = Overflow +~29 * ~128 = Overflow +~29 * ~64 = Overflow +~29 * ~32 = Overflow +~29 * ~16 = Overflow +~29 * ~8 = Overflow +~28 * ~128 = Overflow +~28 * ~64 = Overflow +~28 * ~32 = Overflow +~28 * ~16 = Overflow +~28 * ~8 = Overflow +~27 * ~128 = Overflow +~27 * ~64 = Overflow +~27 * ~32 = Overflow +~27 * ~16 = Overflow +~27 * ~8 = Overflow +~26 * ~128 = Overflow +~26 * ~64 = Overflow +~26 * ~32 = Overflow +~26 * ~16 = Overflow +~26 * ~8 = Overflow +~25 * ~128 = Overflow +~25 * ~64 = Overflow +~25 * ~32 = Overflow +~25 * ~16 = Overflow +~25 * ~8 = Overflow +~24 * ~128 = Overflow +~24 * ~64 = Overflow +~24 * ~32 = Overflow +~24 * ~16 = Overflow +~24 * ~8 = Overflow +~23 * ~128 = Overflow +~23 * ~64 = Overflow +~23 * ~32 = Overflow +~23 * ~16 = Overflow +~23 * ~8 = Overflow +~22 * ~128 = Overflow +~22 * ~64 = Overflow +~22 * ~32 = Overflow +~22 * ~16 = Overflow +~22 * ~8 = Overflow +~21 * ~128 = Overflow +~21 * ~64 = Overflow +~21 * ~32 = Overflow +~21 * ~16 = Overflow +~21 * ~8 = Overflow +~20 * ~128 = Overflow +~20 * ~64 = Overflow +~20 * ~32 = Overflow +~20 * ~16 = Overflow +~20 * ~8 = Overflow +~19 * ~128 = Overflow +~19 * ~64 = Overflow +~19 * ~32 = Overflow +~19 * ~16 = Overflow +~19 * ~8 = Overflow +~18 * ~128 = Overflow +~18 * ~64 = Overflow +~18 * ~32 = Overflow +~18 * ~16 = Overflow +~18 * ~8 = Overflow +~17 * ~128 = Overflow +~17 * ~64 = Overflow +~17 * ~32 = Overflow +~17 * ~16 = Overflow +~17 * ~8 = Overflow +~16 * ~128 = Overflow +~16 * ~64 = Overflow +~16 * ~32 = Overflow +~16 * ~16 = Overflow +~16 * ~8 = Overflow +~15 * ~128 = Overflow +~15 * ~64 = Overflow +~15 * ~32 = Overflow +~15 * ~16 = Overflow +~15 * ~8 = 120 +~14 * ~128 = Overflow +~14 * ~64 = Overflow +~14 * ~32 = Overflow +~14 * ~16 = Overflow +~14 * ~8 = 112 +~13 * ~128 = Overflow +~13 * ~64 = Overflow +~13 * ~32 = Overflow +~13 * ~16 = Overflow +~13 * ~8 = 104 +~12 * ~128 = Overflow +~12 * ~64 = Overflow +~12 * ~32 = Overflow +~12 * ~16 = Overflow +~12 * ~8 = 96 +~11 * ~128 = Overflow +~11 * ~64 = Overflow +~11 * ~32 = Overflow +~11 * ~16 = Overflow +~11 * ~8 = 88 +~10 * ~128 = Overflow +~10 * ~64 = Overflow +~10 * ~32 = Overflow +~10 * ~16 = Overflow +~10 * ~8 = 80 +~9 * ~128 = Overflow +~9 * ~64 = Overflow +~9 * ~32 = Overflow +~9 * ~16 = Overflow +~9 * ~8 = 72 +~8 * ~128 = Overflow +~8 * ~64 = Overflow +~8 * ~32 = Overflow +~8 * ~16 = Overflow +~8 * ~8 = 64 +~7 * ~128 = Overflow +~7 * ~64 = Overflow +~7 * ~32 = Overflow +~7 * ~16 = 112 +~7 * ~8 = 56 +~6 * ~128 = Overflow +~6 * ~64 = Overflow +~6 * ~32 = Overflow +~6 * ~16 = 96 +~6 * ~8 = 48 +~5 * ~128 = Overflow +~5 * ~64 = Overflow +~5 * ~32 = Overflow +~5 * ~16 = 80 +~5 * ~8 = 40 +~4 * ~128 = Overflow +~4 * ~64 = Overflow +~4 * ~32 = Overflow +~4 * ~16 = 64 +~4 * ~8 = 32 +~3 * ~128 = Overflow +~3 * ~64 = Overflow +~3 * ~32 = 96 +~3 * ~16 = 48 +~3 * ~8 = 24 +~2 * ~128 = Overflow +~2 * ~64 = Overflow +~2 * ~32 = 64 +~2 * ~16 = 32 +~2 * ~8 = 16 +~1 * ~128 = Overflow +~1 * ~64 = 64 +~1 * ~32 = 32 +~1 * ~16 = 16 +~1 * ~8 = 8 +0 * ~128 = 0 +0 * ~64 = 0 +0 * ~32 = 0 +0 * ~16 = 0 +0 * ~8 = 0 +1 * ~128 = ~128 +1 * ~64 = ~64 +1 * ~32 = ~32 +1 * ~16 = ~16 +1 * ~8 = ~8 +2 * ~128 = Overflow +2 * ~64 = ~128 +2 * ~32 = ~64 +2 * ~16 = ~32 +2 * ~8 = ~16 +3 * ~128 = Overflow +3 * ~64 = Overflow +3 * ~32 = ~96 +3 * ~16 = ~48 +3 * ~8 = ~24 +4 * ~128 = Overflow +4 * ~64 = Overflow +4 * ~32 = ~128 +4 * ~16 = ~64 +4 * ~8 = ~32 +5 * ~128 = Overflow +5 * ~64 = Overflow +5 * ~32 = Overflow +5 * ~16 = ~80 +5 * ~8 = ~40 +6 * ~128 = Overflow +6 * ~64 = Overflow +6 * ~32 = Overflow +6 * ~16 = ~96 +6 * ~8 = ~48 +7 * ~128 = Overflow +7 * ~64 = Overflow +7 * ~32 = Overflow +7 * ~16 = ~112 +7 * ~8 = ~56 +8 * ~128 = Overflow +8 * ~64 = Overflow +8 * ~32 = Overflow +8 * ~16 = ~128 +8 * ~8 = ~64 +9 * ~128 = Overflow +9 * ~64 = Overflow +9 * ~32 = Overflow +9 * ~16 = Overflow +9 * ~8 = ~72 +10 * ~128 = Overflow +10 * ~64 = Overflow +10 * ~32 = Overflow +10 * ~16 = Overflow +10 * ~8 = ~80 +11 * ~128 = Overflow +11 * ~64 = Overflow +11 * ~32 = Overflow +11 * ~16 = Overflow +11 * ~8 = ~88 +12 * ~128 = Overflow +12 * ~64 = Overflow +12 * ~32 = Overflow +12 * ~16 = Overflow +12 * ~8 = ~96 +13 * ~128 = Overflow +13 * ~64 = Overflow +13 * ~32 = Overflow +13 * ~16 = Overflow +13 * ~8 = ~104 +14 * ~128 = Overflow +14 * ~64 = Overflow +14 * ~32 = Overflow +14 * ~16 = Overflow +14 * ~8 = ~112 +15 * ~128 = Overflow +15 * ~64 = Overflow +15 * ~32 = Overflow +15 * ~16 = Overflow +15 * ~8 = ~120 +16 * ~128 = Overflow +16 * ~64 = Overflow +16 * ~32 = Overflow +16 * ~16 = Overflow +16 * ~8 = ~128 +17 * ~128 = Overflow +17 * ~64 = Overflow +17 * ~32 = Overflow +17 * ~16 = Overflow +17 * ~8 = Overflow +18 * ~128 = Overflow +18 * ~64 = Overflow +18 * ~32 = Overflow +18 * ~16 = Overflow +18 * ~8 = Overflow +19 * ~128 = Overflow +19 * ~64 = Overflow +19 * ~32 = Overflow +19 * ~16 = Overflow +19 * ~8 = Overflow +20 * ~128 = Overflow +20 * ~64 = Overflow +20 * ~32 = Overflow +20 * ~16 = Overflow +20 * ~8 = Overflow +21 * ~128 = Overflow +21 * ~64 = Overflow +21 * ~32 = Overflow +21 * ~16 = Overflow +21 * ~8 = Overflow +22 * ~128 = Overflow +22 * ~64 = Overflow +22 * ~32 = Overflow +22 * ~16 = Overflow +22 * ~8 = Overflow +23 * ~128 = Overflow +23 * ~64 = Overflow +23 * ~32 = Overflow +23 * ~16 = Overflow +23 * ~8 = Overflow +24 * ~128 = Overflow +24 * ~64 = Overflow +24 * ~32 = Overflow +24 * ~16 = Overflow +24 * ~8 = Overflow +25 * ~128 = Overflow +25 * ~64 = Overflow +25 * ~32 = Overflow +25 * ~16 = Overflow +25 * ~8 = Overflow +26 * ~128 = Overflow +26 * ~64 = Overflow +26 * ~32 = Overflow +26 * ~16 = Overflow +26 * ~8 = Overflow +27 * ~128 = Overflow +27 * ~64 = Overflow +27 * ~32 = Overflow +27 * ~16 = Overflow +27 * ~8 = Overflow +28 * ~128 = Overflow +28 * ~64 = Overflow +28 * ~32 = Overflow +28 * ~16 = Overflow +28 * ~8 = Overflow +29 * ~128 = Overflow +29 * ~64 = Overflow +29 * ~32 = Overflow +29 * ~16 = Overflow +29 * ~8 = Overflow +30 * ~128 = Overflow +30 * ~64 = Overflow +30 * ~32 = Overflow +30 * ~16 = Overflow +30 * ~8 = Overflow +31 * ~128 = Overflow +31 * ~64 = Overflow +31 * ~32 = Overflow +31 * ~16 = Overflow +31 * ~8 = Overflow +32 * ~128 = Overflow +32 * ~64 = Overflow +32 * ~32 = Overflow +32 * ~16 = Overflow +32 * ~8 = Overflow +~128 * 1 = ~128 +~128 * 2 = Overflow +~128 * 4 = Overflow +~128 * 8 = Overflow +~128 * 16 = Overflow +~64 * 1 = ~64 +~64 * 2 = ~128 +~64 * 4 = Overflow +~64 * 8 = Overflow +~64 * 16 = Overflow +~32 * 1 = ~32 +~32 * 2 = ~64 +~32 * 4 = ~128 +~32 * 8 = Overflow +~32 * 16 = Overflow +~16 * 1 = ~16 +~16 * 2 = ~32 +~16 * 4 = ~64 +~16 * 8 = ~128 +~16 * 16 = Overflow +~8 * 1 = ~8 +~8 * 2 = ~16 +~8 * 4 = ~32 +~8 * 8 = ~64 +~8 * 16 = ~128 +~4 * 1 = ~4 +~4 * 2 = ~8 +~4 * 4 = ~16 +~4 * 8 = ~32 +~4 * 16 = ~64 +~4 * 1 = ~4 +~4 * 2 = ~8 +~4 * 4 = ~16 +~4 * 8 = ~32 +~4 * 16 = ~64 +~3 * 1 = ~3 +~3 * 2 = ~6 +~3 * 4 = ~12 +~3 * 8 = ~24 +~3 * 16 = ~48 +~2 * 1 = ~2 +~2 * 2 = ~4 +~2 * 4 = ~8 +~2 * 8 = ~16 +~2 * 16 = ~32 +~1 * 1 = ~1 +~1 * 2 = ~2 +~1 * 4 = ~4 +~1 * 8 = ~8 +~1 * 16 = ~16 +0 * 1 = 0 +0 * 2 = 0 +0 * 4 = 0 +0 * 8 = 0 +0 * 16 = 0 +1 * 1 = 1 +1 * 2 = 2 +1 * 4 = 4 +1 * 8 = 8 +1 * 16 = 16 +2 * 1 = 2 +2 * 2 = 4 +2 * 4 = 8 +2 * 8 = 16 +2 * 16 = 32 +3 * 1 = 3 +3 * 2 = 6 +3 * 4 = 12 +3 * 8 = 24 +3 * 16 = 48 +4 * 1 = 4 +4 * 2 = 8 +4 * 4 = 16 +4 * 8 = 32 +4 * 16 = 64 +2 * 1 = 2 +2 * 2 = 4 +2 * 4 = 8 +2 * 8 = 16 +2 * 16 = 32 +4 * 1 = 4 +4 * 2 = 8 +4 * 4 = 16 +4 * 8 = 32 +4 * 16 = 64 +8 * 1 = 8 +8 * 2 = 16 +8 * 4 = 32 +8 * 8 = 64 +8 * 16 = Overflow +16 * 1 = 16 +16 * 2 = 32 +16 * 4 = 64 +16 * 8 = Overflow +16 * 16 = Overflow +32 * 1 = 32 +32 * 2 = 64 +32 * 4 = Overflow +32 * 8 = Overflow +32 * 16 = Overflow +64 * 1 = 64 +64 * 2 = Overflow +64 * 4 = Overflow +64 * 8 = Overflow +64 * 16 = Overflow +~128 * ~1 = Overflow +~128 * ~2 = Overflow +~128 * ~4 = Overflow +~128 * ~8 = Overflow +~128 * ~16 = Overflow +~64 * ~1 = 64 +~64 * ~2 = Overflow +~64 * ~4 = Overflow +~64 * ~8 = Overflow +~64 * ~16 = Overflow +~32 * ~1 = 32 +~32 * ~2 = 64 +~32 * ~4 = Overflow +~32 * ~8 = Overflow +~32 * ~16 = Overflow +~16 * ~1 = 16 +~16 * ~2 = 32 +~16 * ~4 = 64 +~16 * ~8 = Overflow +~16 * ~16 = Overflow +~8 * ~1 = 8 +~8 * ~2 = 16 +~8 * ~4 = 32 +~8 * ~8 = 64 +~8 * ~16 = Overflow +~4 * ~1 = 4 +~4 * ~2 = 8 +~4 * ~4 = 16 +~4 * ~8 = 32 +~4 * ~16 = 64 +~4 * ~1 = 4 +~4 * ~2 = 8 +~4 * ~4 = 16 +~4 * ~8 = 32 +~4 * ~16 = 64 +~3 * ~1 = 3 +~3 * ~2 = 6 +~3 * ~4 = 12 +~3 * ~8 = 24 +~3 * ~16 = 48 +~2 * ~1 = 2 +~2 * ~2 = 4 +~2 * ~4 = 8 +~2 * ~8 = 16 +~2 * ~16 = 32 +~1 * ~1 = 1 +~1 * ~2 = 2 +~1 * ~4 = 4 +~1 * ~8 = 8 +~1 * ~16 = 16 +0 * ~1 = 0 +0 * ~2 = 0 +0 * ~4 = 0 +0 * ~8 = 0 +0 * ~16 = 0 +1 * ~1 = ~1 +1 * ~2 = ~2 +1 * ~4 = ~4 +1 * ~8 = ~8 +1 * ~16 = ~16 +2 * ~1 = ~2 +2 * ~2 = ~4 +2 * ~4 = ~8 +2 * ~8 = ~16 +2 * ~16 = ~32 +3 * ~1 = ~3 +3 * ~2 = ~6 +3 * ~4 = ~12 +3 * ~8 = ~24 +3 * ~16 = ~48 +4 * ~1 = ~4 +4 * ~2 = ~8 +4 * ~4 = ~16 +4 * ~8 = ~32 +4 * ~16 = ~64 +2 * ~1 = ~2 +2 * ~2 = ~4 +2 * ~4 = ~8 +2 * ~8 = ~16 +2 * ~16 = ~32 +4 * ~1 = ~4 +4 * ~2 = ~8 +4 * ~4 = ~16 +4 * ~8 = ~32 +4 * ~16 = ~64 +8 * ~1 = ~8 +8 * ~2 = ~16 +8 * ~4 = ~32 +8 * ~8 = ~64 +8 * ~16 = ~128 +16 * ~1 = ~16 +16 * ~2 = ~32 +16 * ~4 = ~64 +16 * ~8 = ~128 +16 * ~16 = Overflow +32 * ~1 = ~32 +32 * ~2 = ~64 +32 * ~4 = ~128 +32 * ~8 = Overflow +32 * ~16 = Overflow +64 * ~1 = ~64 +64 * ~2 = ~128 +64 * ~4 = Overflow +64 * ~8 = Overflow +64 * ~16 = Overflow +~32 * 16384 = Overflow +~32 * 8192 = Overflow +~32 * 4096 = Overflow +~32 * 2048 = Overflow +~32 * 1024 = ~32768 +~31 * 16384 = Overflow +~31 * 8192 = Overflow +~31 * 4096 = Overflow +~31 * 2048 = Overflow +~31 * 1024 = ~31744 +~30 * 16384 = Overflow +~30 * 8192 = Overflow +~30 * 4096 = Overflow +~30 * 2048 = Overflow +~30 * 1024 = ~30720 +~29 * 16384 = Overflow +~29 * 8192 = Overflow +~29 * 4096 = Overflow +~29 * 2048 = Overflow +~29 * 1024 = ~29696 +~28 * 16384 = Overflow +~28 * 8192 = Overflow +~28 * 4096 = Overflow +~28 * 2048 = Overflow +~28 * 1024 = ~28672 +~27 * 16384 = Overflow +~27 * 8192 = Overflow +~27 * 4096 = Overflow +~27 * 2048 = Overflow +~27 * 1024 = ~27648 +~26 * 16384 = Overflow +~26 * 8192 = Overflow +~26 * 4096 = Overflow +~26 * 2048 = Overflow +~26 * 1024 = ~26624 +~25 * 16384 = Overflow +~25 * 8192 = Overflow +~25 * 4096 = Overflow +~25 * 2048 = Overflow +~25 * 1024 = ~25600 +~24 * 16384 = Overflow +~24 * 8192 = Overflow +~24 * 4096 = Overflow +~24 * 2048 = Overflow +~24 * 1024 = ~24576 +~23 * 16384 = Overflow +~23 * 8192 = Overflow +~23 * 4096 = Overflow +~23 * 2048 = Overflow +~23 * 1024 = ~23552 +~22 * 16384 = Overflow +~22 * 8192 = Overflow +~22 * 4096 = Overflow +~22 * 2048 = Overflow +~22 * 1024 = ~22528 +~21 * 16384 = Overflow +~21 * 8192 = Overflow +~21 * 4096 = Overflow +~21 * 2048 = Overflow +~21 * 1024 = ~21504 +~20 * 16384 = Overflow +~20 * 8192 = Overflow +~20 * 4096 = Overflow +~20 * 2048 = Overflow +~20 * 1024 = ~20480 +~19 * 16384 = Overflow +~19 * 8192 = Overflow +~19 * 4096 = Overflow +~19 * 2048 = Overflow +~19 * 1024 = ~19456 +~18 * 16384 = Overflow +~18 * 8192 = Overflow +~18 * 4096 = Overflow +~18 * 2048 = Overflow +~18 * 1024 = ~18432 +~17 * 16384 = Overflow +~17 * 8192 = Overflow +~17 * 4096 = Overflow +~17 * 2048 = Overflow +~17 * 1024 = ~17408 +~16 * 16384 = Overflow +~16 * 8192 = Overflow +~16 * 4096 = Overflow +~16 * 2048 = ~32768 +~16 * 1024 = ~16384 +~15 * 16384 = Overflow +~15 * 8192 = Overflow +~15 * 4096 = Overflow +~15 * 2048 = ~30720 +~15 * 1024 = ~15360 +~14 * 16384 = Overflow +~14 * 8192 = Overflow +~14 * 4096 = Overflow +~14 * 2048 = ~28672 +~14 * 1024 = ~14336 +~13 * 16384 = Overflow +~13 * 8192 = Overflow +~13 * 4096 = Overflow +~13 * 2048 = ~26624 +~13 * 1024 = ~13312 +~12 * 16384 = Overflow +~12 * 8192 = Overflow +~12 * 4096 = Overflow +~12 * 2048 = ~24576 +~12 * 1024 = ~12288 +~11 * 16384 = Overflow +~11 * 8192 = Overflow +~11 * 4096 = Overflow +~11 * 2048 = ~22528 +~11 * 1024 = ~11264 +~10 * 16384 = Overflow +~10 * 8192 = Overflow +~10 * 4096 = Overflow +~10 * 2048 = ~20480 +~10 * 1024 = ~10240 +~9 * 16384 = Overflow +~9 * 8192 = Overflow +~9 * 4096 = Overflow +~9 * 2048 = ~18432 +~9 * 1024 = ~9216 +~8 * 16384 = Overflow +~8 * 8192 = Overflow +~8 * 4096 = ~32768 +~8 * 2048 = ~16384 +~8 * 1024 = ~8192 +~7 * 16384 = Overflow +~7 * 8192 = Overflow +~7 * 4096 = ~28672 +~7 * 2048 = ~14336 +~7 * 1024 = ~7168 +~6 * 16384 = Overflow +~6 * 8192 = Overflow +~6 * 4096 = ~24576 +~6 * 2048 = ~12288 +~6 * 1024 = ~6144 +~5 * 16384 = Overflow +~5 * 8192 = Overflow +~5 * 4096 = ~20480 +~5 * 2048 = ~10240 +~5 * 1024 = ~5120 +~4 * 16384 = Overflow +~4 * 8192 = ~32768 +~4 * 4096 = ~16384 +~4 * 2048 = ~8192 +~4 * 1024 = ~4096 +~3 * 16384 = Overflow +~3 * 8192 = ~24576 +~3 * 4096 = ~12288 +~3 * 2048 = ~6144 +~3 * 1024 = ~3072 +~2 * 16384 = ~32768 +~2 * 8192 = ~16384 +~2 * 4096 = ~8192 +~2 * 2048 = ~4096 +~2 * 1024 = ~2048 +~1 * 16384 = ~16384 +~1 * 8192 = ~8192 +~1 * 4096 = ~4096 +~1 * 2048 = ~2048 +~1 * 1024 = ~1024 +0 * 16384 = 0 +0 * 8192 = 0 +0 * 4096 = 0 +0 * 2048 = 0 +0 * 1024 = 0 +1 * 16384 = 16384 +1 * 8192 = 8192 +1 * 4096 = 4096 +1 * 2048 = 2048 +1 * 1024 = 1024 +2 * 16384 = Overflow +2 * 8192 = 16384 +2 * 4096 = 8192 +2 * 2048 = 4096 +2 * 1024 = 2048 +3 * 16384 = Overflow +3 * 8192 = 24576 +3 * 4096 = 12288 +3 * 2048 = 6144 +3 * 1024 = 3072 +4 * 16384 = Overflow +4 * 8192 = Overflow +4 * 4096 = 16384 +4 * 2048 = 8192 +4 * 1024 = 4096 +5 * 16384 = Overflow +5 * 8192 = Overflow +5 * 4096 = 20480 +5 * 2048 = 10240 +5 * 1024 = 5120 +6 * 16384 = Overflow +6 * 8192 = Overflow +6 * 4096 = 24576 +6 * 2048 = 12288 +6 * 1024 = 6144 +7 * 16384 = Overflow +7 * 8192 = Overflow +7 * 4096 = 28672 +7 * 2048 = 14336 +7 * 1024 = 7168 +8 * 16384 = Overflow +8 * 8192 = Overflow +8 * 4096 = Overflow +8 * 2048 = 16384 +8 * 1024 = 8192 +9 * 16384 = Overflow +9 * 8192 = Overflow +9 * 4096 = Overflow +9 * 2048 = 18432 +9 * 1024 = 9216 +10 * 16384 = Overflow +10 * 8192 = Overflow +10 * 4096 = Overflow +10 * 2048 = 20480 +10 * 1024 = 10240 +11 * 16384 = Overflow +11 * 8192 = Overflow +11 * 4096 = Overflow +11 * 2048 = 22528 +11 * 1024 = 11264 +12 * 16384 = Overflow +12 * 8192 = Overflow +12 * 4096 = Overflow +12 * 2048 = 24576 +12 * 1024 = 12288 +13 * 16384 = Overflow +13 * 8192 = Overflow +13 * 4096 = Overflow +13 * 2048 = 26624 +13 * 1024 = 13312 +14 * 16384 = Overflow +14 * 8192 = Overflow +14 * 4096 = Overflow +14 * 2048 = 28672 +14 * 1024 = 14336 +15 * 16384 = Overflow +15 * 8192 = Overflow +15 * 4096 = Overflow +15 * 2048 = 30720 +15 * 1024 = 15360 +16 * 16384 = Overflow +16 * 8192 = Overflow +16 * 4096 = Overflow +16 * 2048 = Overflow +16 * 1024 = 16384 +17 * 16384 = Overflow +17 * 8192 = Overflow +17 * 4096 = Overflow +17 * 2048 = Overflow +17 * 1024 = 17408 +18 * 16384 = Overflow +18 * 8192 = Overflow +18 * 4096 = Overflow +18 * 2048 = Overflow +18 * 1024 = 18432 +19 * 16384 = Overflow +19 * 8192 = Overflow +19 * 4096 = Overflow +19 * 2048 = Overflow +19 * 1024 = 19456 +20 * 16384 = Overflow +20 * 8192 = Overflow +20 * 4096 = Overflow +20 * 2048 = Overflow +20 * 1024 = 20480 +21 * 16384 = Overflow +21 * 8192 = Overflow +21 * 4096 = Overflow +21 * 2048 = Overflow +21 * 1024 = 21504 +22 * 16384 = Overflow +22 * 8192 = Overflow +22 * 4096 = Overflow +22 * 2048 = Overflow +22 * 1024 = 22528 +23 * 16384 = Overflow +23 * 8192 = Overflow +23 * 4096 = Overflow +23 * 2048 = Overflow +23 * 1024 = 23552 +24 * 16384 = Overflow +24 * 8192 = Overflow +24 * 4096 = Overflow +24 * 2048 = Overflow +24 * 1024 = 24576 +25 * 16384 = Overflow +25 * 8192 = Overflow +25 * 4096 = Overflow +25 * 2048 = Overflow +25 * 1024 = 25600 +26 * 16384 = Overflow +26 * 8192 = Overflow +26 * 4096 = Overflow +26 * 2048 = Overflow +26 * 1024 = 26624 +27 * 16384 = Overflow +27 * 8192 = Overflow +27 * 4096 = Overflow +27 * 2048 = Overflow +27 * 1024 = 27648 +28 * 16384 = Overflow +28 * 8192 = Overflow +28 * 4096 = Overflow +28 * 2048 = Overflow +28 * 1024 = 28672 +29 * 16384 = Overflow +29 * 8192 = Overflow +29 * 4096 = Overflow +29 * 2048 = Overflow +29 * 1024 = 29696 +30 * 16384 = Overflow +30 * 8192 = Overflow +30 * 4096 = Overflow +30 * 2048 = Overflow +30 * 1024 = 30720 +31 * 16384 = Overflow +31 * 8192 = Overflow +31 * 4096 = Overflow +31 * 2048 = Overflow +31 * 1024 = 31744 +32 * 16384 = Overflow +32 * 8192 = Overflow +32 * 4096 = Overflow +32 * 2048 = Overflow +32 * 1024 = Overflow +~32 * ~32768 = Overflow +~32 * ~16384 = Overflow +~32 * ~8192 = Overflow +~32 * ~4096 = Overflow +~32 * ~2048 = Overflow +~31 * ~32768 = Overflow +~31 * ~16384 = Overflow +~31 * ~8192 = Overflow +~31 * ~4096 = Overflow +~31 * ~2048 = Overflow +~30 * ~32768 = Overflow +~30 * ~16384 = Overflow +~30 * ~8192 = Overflow +~30 * ~4096 = Overflow +~30 * ~2048 = Overflow +~29 * ~32768 = Overflow +~29 * ~16384 = Overflow +~29 * ~8192 = Overflow +~29 * ~4096 = Overflow +~29 * ~2048 = Overflow +~28 * ~32768 = Overflow +~28 * ~16384 = Overflow +~28 * ~8192 = Overflow +~28 * ~4096 = Overflow +~28 * ~2048 = Overflow +~27 * ~32768 = Overflow +~27 * ~16384 = Overflow +~27 * ~8192 = Overflow +~27 * ~4096 = Overflow +~27 * ~2048 = Overflow +~26 * ~32768 = Overflow +~26 * ~16384 = Overflow +~26 * ~8192 = Overflow +~26 * ~4096 = Overflow +~26 * ~2048 = Overflow +~25 * ~32768 = Overflow +~25 * ~16384 = Overflow +~25 * ~8192 = Overflow +~25 * ~4096 = Overflow +~25 * ~2048 = Overflow +~24 * ~32768 = Overflow +~24 * ~16384 = Overflow +~24 * ~8192 = Overflow +~24 * ~4096 = Overflow +~24 * ~2048 = Overflow +~23 * ~32768 = Overflow +~23 * ~16384 = Overflow +~23 * ~8192 = Overflow +~23 * ~4096 = Overflow +~23 * ~2048 = Overflow +~22 * ~32768 = Overflow +~22 * ~16384 = Overflow +~22 * ~8192 = Overflow +~22 * ~4096 = Overflow +~22 * ~2048 = Overflow +~21 * ~32768 = Overflow +~21 * ~16384 = Overflow +~21 * ~8192 = Overflow +~21 * ~4096 = Overflow +~21 * ~2048 = Overflow +~20 * ~32768 = Overflow +~20 * ~16384 = Overflow +~20 * ~8192 = Overflow +~20 * ~4096 = Overflow +~20 * ~2048 = Overflow +~19 * ~32768 = Overflow +~19 * ~16384 = Overflow +~19 * ~8192 = Overflow +~19 * ~4096 = Overflow +~19 * ~2048 = Overflow +~18 * ~32768 = Overflow +~18 * ~16384 = Overflow +~18 * ~8192 = Overflow +~18 * ~4096 = Overflow +~18 * ~2048 = Overflow +~17 * ~32768 = Overflow +~17 * ~16384 = Overflow +~17 * ~8192 = Overflow +~17 * ~4096 = Overflow +~17 * ~2048 = Overflow +~16 * ~32768 = Overflow +~16 * ~16384 = Overflow +~16 * ~8192 = Overflow +~16 * ~4096 = Overflow +~16 * ~2048 = Overflow +~15 * ~32768 = Overflow +~15 * ~16384 = Overflow +~15 * ~8192 = Overflow +~15 * ~4096 = Overflow +~15 * ~2048 = 30720 +~14 * ~32768 = Overflow +~14 * ~16384 = Overflow +~14 * ~8192 = Overflow +~14 * ~4096 = Overflow +~14 * ~2048 = 28672 +~13 * ~32768 = Overflow +~13 * ~16384 = Overflow +~13 * ~8192 = Overflow +~13 * ~4096 = Overflow +~13 * ~2048 = 26624 +~12 * ~32768 = Overflow +~12 * ~16384 = Overflow +~12 * ~8192 = Overflow +~12 * ~4096 = Overflow +~12 * ~2048 = 24576 +~11 * ~32768 = Overflow +~11 * ~16384 = Overflow +~11 * ~8192 = Overflow +~11 * ~4096 = Overflow +~11 * ~2048 = 22528 +~10 * ~32768 = Overflow +~10 * ~16384 = Overflow +~10 * ~8192 = Overflow +~10 * ~4096 = Overflow +~10 * ~2048 = 20480 +~9 * ~32768 = Overflow +~9 * ~16384 = Overflow +~9 * ~8192 = Overflow +~9 * ~4096 = Overflow +~9 * ~2048 = 18432 +~8 * ~32768 = Overflow +~8 * ~16384 = Overflow +~8 * ~8192 = Overflow +~8 * ~4096 = Overflow +~8 * ~2048 = 16384 +~7 * ~32768 = Overflow +~7 * ~16384 = Overflow +~7 * ~8192 = Overflow +~7 * ~4096 = 28672 +~7 * ~2048 = 14336 +~6 * ~32768 = Overflow +~6 * ~16384 = Overflow +~6 * ~8192 = Overflow +~6 * ~4096 = 24576 +~6 * ~2048 = 12288 +~5 * ~32768 = Overflow +~5 * ~16384 = Overflow +~5 * ~8192 = Overflow +~5 * ~4096 = 20480 +~5 * ~2048 = 10240 +~4 * ~32768 = Overflow +~4 * ~16384 = Overflow +~4 * ~8192 = Overflow +~4 * ~4096 = 16384 +~4 * ~2048 = 8192 +~3 * ~32768 = Overflow +~3 * ~16384 = Overflow +~3 * ~8192 = 24576 +~3 * ~4096 = 12288 +~3 * ~2048 = 6144 +~2 * ~32768 = Overflow +~2 * ~16384 = Overflow +~2 * ~8192 = 16384 +~2 * ~4096 = 8192 +~2 * ~2048 = 4096 +~1 * ~32768 = Overflow +~1 * ~16384 = 16384 +~1 * ~8192 = 8192 +~1 * ~4096 = 4096 +~1 * ~2048 = 2048 +0 * ~32768 = 0 +0 * ~16384 = 0 +0 * ~8192 = 0 +0 * ~4096 = 0 +0 * ~2048 = 0 +1 * ~32768 = ~32768 +1 * ~16384 = ~16384 +1 * ~8192 = ~8192 +1 * ~4096 = ~4096 +1 * ~2048 = ~2048 +2 * ~32768 = Overflow +2 * ~16384 = ~32768 +2 * ~8192 = ~16384 +2 * ~4096 = ~8192 +2 * ~2048 = ~4096 +3 * ~32768 = Overflow +3 * ~16384 = Overflow +3 * ~8192 = ~24576 +3 * ~4096 = ~12288 +3 * ~2048 = ~6144 +4 * ~32768 = Overflow +4 * ~16384 = Overflow +4 * ~8192 = ~32768 +4 * ~4096 = ~16384 +4 * ~2048 = ~8192 +5 * ~32768 = Overflow +5 * ~16384 = Overflow +5 * ~8192 = Overflow +5 * ~4096 = ~20480 +5 * ~2048 = ~10240 +6 * ~32768 = Overflow +6 * ~16384 = Overflow +6 * ~8192 = Overflow +6 * ~4096 = ~24576 +6 * ~2048 = ~12288 +7 * ~32768 = Overflow +7 * ~16384 = Overflow +7 * ~8192 = Overflow +7 * ~4096 = ~28672 +7 * ~2048 = ~14336 +8 * ~32768 = Overflow +8 * ~16384 = Overflow +8 * ~8192 = Overflow +8 * ~4096 = ~32768 +8 * ~2048 = ~16384 +9 * ~32768 = Overflow +9 * ~16384 = Overflow +9 * ~8192 = Overflow +9 * ~4096 = Overflow +9 * ~2048 = ~18432 +10 * ~32768 = Overflow +10 * ~16384 = Overflow +10 * ~8192 = Overflow +10 * ~4096 = Overflow +10 * ~2048 = ~20480 +11 * ~32768 = Overflow +11 * ~16384 = Overflow +11 * ~8192 = Overflow +11 * ~4096 = Overflow +11 * ~2048 = ~22528 +12 * ~32768 = Overflow +12 * ~16384 = Overflow +12 * ~8192 = Overflow +12 * ~4096 = Overflow +12 * ~2048 = ~24576 +13 * ~32768 = Overflow +13 * ~16384 = Overflow +13 * ~8192 = Overflow +13 * ~4096 = Overflow +13 * ~2048 = ~26624 +14 * ~32768 = Overflow +14 * ~16384 = Overflow +14 * ~8192 = Overflow +14 * ~4096 = Overflow +14 * ~2048 = ~28672 +15 * ~32768 = Overflow +15 * ~16384 = Overflow +15 * ~8192 = Overflow +15 * ~4096 = Overflow +15 * ~2048 = ~30720 +16 * ~32768 = Overflow +16 * ~16384 = Overflow +16 * ~8192 = Overflow +16 * ~4096 = Overflow +16 * ~2048 = ~32768 +17 * ~32768 = Overflow +17 * ~16384 = Overflow +17 * ~8192 = Overflow +17 * ~4096 = Overflow +17 * ~2048 = Overflow +18 * ~32768 = Overflow +18 * ~16384 = Overflow +18 * ~8192 = Overflow +18 * ~4096 = Overflow +18 * ~2048 = Overflow +19 * ~32768 = Overflow +19 * ~16384 = Overflow +19 * ~8192 = Overflow +19 * ~4096 = Overflow +19 * ~2048 = Overflow +20 * ~32768 = Overflow +20 * ~16384 = Overflow +20 * ~8192 = Overflow +20 * ~4096 = Overflow +20 * ~2048 = Overflow +21 * ~32768 = Overflow +21 * ~16384 = Overflow +21 * ~8192 = Overflow +21 * ~4096 = Overflow +21 * ~2048 = Overflow +22 * ~32768 = Overflow +22 * ~16384 = Overflow +22 * ~8192 = Overflow +22 * ~4096 = Overflow +22 * ~2048 = Overflow +23 * ~32768 = Overflow +23 * ~16384 = Overflow +23 * ~8192 = Overflow +23 * ~4096 = Overflow +23 * ~2048 = Overflow +24 * ~32768 = Overflow +24 * ~16384 = Overflow +24 * ~8192 = Overflow +24 * ~4096 = Overflow +24 * ~2048 = Overflow +25 * ~32768 = Overflow +25 * ~16384 = Overflow +25 * ~8192 = Overflow +25 * ~4096 = Overflow +25 * ~2048 = Overflow +26 * ~32768 = Overflow +26 * ~16384 = Overflow +26 * ~8192 = Overflow +26 * ~4096 = Overflow +26 * ~2048 = Overflow +27 * ~32768 = Overflow +27 * ~16384 = Overflow +27 * ~8192 = Overflow +27 * ~4096 = Overflow +27 * ~2048 = Overflow +28 * ~32768 = Overflow +28 * ~16384 = Overflow +28 * ~8192 = Overflow +28 * ~4096 = Overflow +28 * ~2048 = Overflow +29 * ~32768 = Overflow +29 * ~16384 = Overflow +29 * ~8192 = Overflow +29 * ~4096 = Overflow +29 * ~2048 = Overflow +30 * ~32768 = Overflow +30 * ~16384 = Overflow +30 * ~8192 = Overflow +30 * ~4096 = Overflow +30 * ~2048 = Overflow +31 * ~32768 = Overflow +31 * ~16384 = Overflow +31 * ~8192 = Overflow +31 * ~4096 = Overflow +31 * ~2048 = Overflow +32 * ~32768 = Overflow +32 * ~16384 = Overflow +32 * ~8192 = Overflow +32 * ~4096 = Overflow +32 * ~2048 = Overflow +~32768 * 1 = ~32768 +~32768 * 2 = Overflow +~32768 * 4 = Overflow +~32768 * 8 = Overflow +~32768 * 16 = Overflow +~16384 * 1 = ~16384 +~16384 * 2 = ~32768 +~16384 * 4 = Overflow +~16384 * 8 = Overflow +~16384 * 16 = Overflow +~8192 * 1 = ~8192 +~8192 * 2 = ~16384 +~8192 * 4 = ~32768 +~8192 * 8 = Overflow +~8192 * 16 = Overflow +~4096 * 1 = ~4096 +~4096 * 2 = ~8192 +~4096 * 4 = ~16384 +~4096 * 8 = ~32768 +~4096 * 16 = Overflow +~2048 * 1 = ~2048 +~2048 * 2 = ~4096 +~2048 * 4 = ~8192 +~2048 * 8 = ~16384 +~2048 * 16 = ~32768 +~1024 * 1 = ~1024 +~1024 * 2 = ~2048 +~1024 * 4 = ~4096 +~1024 * 8 = ~8192 +~1024 * 16 = ~16384 +~4 * 1 = ~4 +~4 * 2 = ~8 +~4 * 4 = ~16 +~4 * 8 = ~32 +~4 * 16 = ~64 +~3 * 1 = ~3 +~3 * 2 = ~6 +~3 * 4 = ~12 +~3 * 8 = ~24 +~3 * 16 = ~48 +~2 * 1 = ~2 +~2 * 2 = ~4 +~2 * 4 = ~8 +~2 * 8 = ~16 +~2 * 16 = ~32 +~1 * 1 = ~1 +~1 * 2 = ~2 +~1 * 4 = ~4 +~1 * 8 = ~8 +~1 * 16 = ~16 +0 * 1 = 0 +0 * 2 = 0 +0 * 4 = 0 +0 * 8 = 0 +0 * 16 = 0 +1 * 1 = 1 +1 * 2 = 2 +1 * 4 = 4 +1 * 8 = 8 +1 * 16 = 16 +2 * 1 = 2 +2 * 2 = 4 +2 * 4 = 8 +2 * 8 = 16 +2 * 16 = 32 +3 * 1 = 3 +3 * 2 = 6 +3 * 4 = 12 +3 * 8 = 24 +3 * 16 = 48 +4 * 1 = 4 +4 * 2 = 8 +4 * 4 = 16 +4 * 8 = 32 +4 * 16 = 64 +512 * 1 = 512 +512 * 2 = 1024 +512 * 4 = 2048 +512 * 8 = 4096 +512 * 16 = 8192 +1024 * 1 = 1024 +1024 * 2 = 2048 +1024 * 4 = 4096 +1024 * 8 = 8192 +1024 * 16 = 16384 +2048 * 1 = 2048 +2048 * 2 = 4096 +2048 * 4 = 8192 +2048 * 8 = 16384 +2048 * 16 = Overflow +4096 * 1 = 4096 +4096 * 2 = 8192 +4096 * 4 = 16384 +4096 * 8 = Overflow +4096 * 16 = Overflow +8192 * 1 = 8192 +8192 * 2 = 16384 +8192 * 4 = Overflow +8192 * 8 = Overflow +8192 * 16 = Overflow +16384 * 1 = 16384 +16384 * 2 = Overflow +16384 * 4 = Overflow +16384 * 8 = Overflow +16384 * 16 = Overflow +~32768 * ~1 = Overflow +~32768 * ~2 = Overflow +~32768 * ~4 = Overflow +~32768 * ~8 = Overflow +~32768 * ~16 = Overflow +~16384 * ~1 = 16384 +~16384 * ~2 = Overflow +~16384 * ~4 = Overflow +~16384 * ~8 = Overflow +~16384 * ~16 = Overflow +~8192 * ~1 = 8192 +~8192 * ~2 = 16384 +~8192 * ~4 = Overflow +~8192 * ~8 = Overflow +~8192 * ~16 = Overflow +~4096 * ~1 = 4096 +~4096 * ~2 = 8192 +~4096 * ~4 = 16384 +~4096 * ~8 = Overflow +~4096 * ~16 = Overflow +~2048 * ~1 = 2048 +~2048 * ~2 = 4096 +~2048 * ~4 = 8192 +~2048 * ~8 = 16384 +~2048 * ~16 = Overflow +~1024 * ~1 = 1024 +~1024 * ~2 = 2048 +~1024 * ~4 = 4096 +~1024 * ~8 = 8192 +~1024 * ~16 = 16384 +~4 * ~1 = 4 +~4 * ~2 = 8 +~4 * ~4 = 16 +~4 * ~8 = 32 +~4 * ~16 = 64 +~3 * ~1 = 3 +~3 * ~2 = 6 +~3 * ~4 = 12 +~3 * ~8 = 24 +~3 * ~16 = 48 +~2 * ~1 = 2 +~2 * ~2 = 4 +~2 * ~4 = 8 +~2 * ~8 = 16 +~2 * ~16 = 32 +~1 * ~1 = 1 +~1 * ~2 = 2 +~1 * ~4 = 4 +~1 * ~8 = 8 +~1 * ~16 = 16 +0 * ~1 = 0 +0 * ~2 = 0 +0 * ~4 = 0 +0 * ~8 = 0 +0 * ~16 = 0 +1 * ~1 = ~1 +1 * ~2 = ~2 +1 * ~4 = ~4 +1 * ~8 = ~8 +1 * ~16 = ~16 +2 * ~1 = ~2 +2 * ~2 = ~4 +2 * ~4 = ~8 +2 * ~8 = ~16 +2 * ~16 = ~32 +3 * ~1 = ~3 +3 * ~2 = ~6 +3 * ~4 = ~12 +3 * ~8 = ~24 +3 * ~16 = ~48 +4 * ~1 = ~4 +4 * ~2 = ~8 +4 * ~4 = ~16 +4 * ~8 = ~32 +4 * ~16 = ~64 +512 * ~1 = ~512 +512 * ~2 = ~1024 +512 * ~4 = ~2048 +512 * ~8 = ~4096 +512 * ~16 = ~8192 +1024 * ~1 = ~1024 +1024 * ~2 = ~2048 +1024 * ~4 = ~4096 +1024 * ~8 = ~8192 +1024 * ~16 = ~16384 +2048 * ~1 = ~2048 +2048 * ~2 = ~4096 +2048 * ~4 = ~8192 +2048 * ~8 = ~16384 +2048 * ~16 = ~32768 +4096 * ~1 = ~4096 +4096 * ~2 = ~8192 +4096 * ~4 = ~16384 +4096 * ~8 = ~32768 +4096 * ~16 = Overflow +8192 * ~1 = ~8192 +8192 * ~2 = ~16384 +8192 * ~4 = ~32768 +8192 * ~8 = Overflow +8192 * ~16 = Overflow +16384 * ~1 = ~16384 +16384 * ~2 = ~32768 +16384 * ~4 = Overflow +16384 * ~8 = Overflow +16384 * ~16 = Overflow +~32 * 1073741824 = Overflow +~32 * 536870912 = Overflow +~32 * 268435456 = Overflow +~32 * 134217728 = Overflow +~32 * 67108864 = ~2147483648 +~31 * 1073741824 = Overflow +~31 * 536870912 = Overflow +~31 * 268435456 = Overflow +~31 * 134217728 = Overflow +~31 * 67108864 = ~2080374784 +~30 * 1073741824 = Overflow +~30 * 536870912 = Overflow +~30 * 268435456 = Overflow +~30 * 134217728 = Overflow +~30 * 67108864 = ~2013265920 +~29 * 1073741824 = Overflow +~29 * 536870912 = Overflow +~29 * 268435456 = Overflow +~29 * 134217728 = Overflow +~29 * 67108864 = ~1946157056 +~28 * 1073741824 = Overflow +~28 * 536870912 = Overflow +~28 * 268435456 = Overflow +~28 * 134217728 = Overflow +~28 * 67108864 = ~1879048192 +~27 * 1073741824 = Overflow +~27 * 536870912 = Overflow +~27 * 268435456 = Overflow +~27 * 134217728 = Overflow +~27 * 67108864 = ~1811939328 +~26 * 1073741824 = Overflow +~26 * 536870912 = Overflow +~26 * 268435456 = Overflow +~26 * 134217728 = Overflow +~26 * 67108864 = ~1744830464 +~25 * 1073741824 = Overflow +~25 * 536870912 = Overflow +~25 * 268435456 = Overflow +~25 * 134217728 = Overflow +~25 * 67108864 = ~1677721600 +~24 * 1073741824 = Overflow +~24 * 536870912 = Overflow +~24 * 268435456 = Overflow +~24 * 134217728 = Overflow +~24 * 67108864 = ~1610612736 +~23 * 1073741824 = Overflow +~23 * 536870912 = Overflow +~23 * 268435456 = Overflow +~23 * 134217728 = Overflow +~23 * 67108864 = ~1543503872 +~22 * 1073741824 = Overflow +~22 * 536870912 = Overflow +~22 * 268435456 = Overflow +~22 * 134217728 = Overflow +~22 * 67108864 = ~1476395008 +~21 * 1073741824 = Overflow +~21 * 536870912 = Overflow +~21 * 268435456 = Overflow +~21 * 134217728 = Overflow +~21 * 67108864 = ~1409286144 +~20 * 1073741824 = Overflow +~20 * 536870912 = Overflow +~20 * 268435456 = Overflow +~20 * 134217728 = Overflow +~20 * 67108864 = ~1342177280 +~19 * 1073741824 = Overflow +~19 * 536870912 = Overflow +~19 * 268435456 = Overflow +~19 * 134217728 = Overflow +~19 * 67108864 = ~1275068416 +~18 * 1073741824 = Overflow +~18 * 536870912 = Overflow +~18 * 268435456 = Overflow +~18 * 134217728 = Overflow +~18 * 67108864 = ~1207959552 +~17 * 1073741824 = Overflow +~17 * 536870912 = Overflow +~17 * 268435456 = Overflow +~17 * 134217728 = Overflow +~17 * 67108864 = ~1140850688 +~16 * 1073741824 = Overflow +~16 * 536870912 = Overflow +~16 * 268435456 = Overflow +~16 * 134217728 = ~2147483648 +~16 * 67108864 = ~1073741824 +~15 * 1073741824 = Overflow +~15 * 536870912 = Overflow +~15 * 268435456 = Overflow +~15 * 134217728 = ~2013265920 +~15 * 67108864 = ~1006632960 +~14 * 1073741824 = Overflow +~14 * 536870912 = Overflow +~14 * 268435456 = Overflow +~14 * 134217728 = ~1879048192 +~14 * 67108864 = ~939524096 +~13 * 1073741824 = Overflow +~13 * 536870912 = Overflow +~13 * 268435456 = Overflow +~13 * 134217728 = ~1744830464 +~13 * 67108864 = ~872415232 +~12 * 1073741824 = Overflow +~12 * 536870912 = Overflow +~12 * 268435456 = Overflow +~12 * 134217728 = ~1610612736 +~12 * 67108864 = ~805306368 +~11 * 1073741824 = Overflow +~11 * 536870912 = Overflow +~11 * 268435456 = Overflow +~11 * 134217728 = ~1476395008 +~11 * 67108864 = ~738197504 +~10 * 1073741824 = Overflow +~10 * 536870912 = Overflow +~10 * 268435456 = Overflow +~10 * 134217728 = ~1342177280 +~10 * 67108864 = ~671088640 +~9 * 1073741824 = Overflow +~9 * 536870912 = Overflow +~9 * 268435456 = Overflow +~9 * 134217728 = ~1207959552 +~9 * 67108864 = ~603979776 +~8 * 1073741824 = Overflow +~8 * 536870912 = Overflow +~8 * 268435456 = ~2147483648 +~8 * 134217728 = ~1073741824 +~8 * 67108864 = ~536870912 +~7 * 1073741824 = Overflow +~7 * 536870912 = Overflow +~7 * 268435456 = ~1879048192 +~7 * 134217728 = ~939524096 +~7 * 67108864 = ~469762048 +~6 * 1073741824 = Overflow +~6 * 536870912 = Overflow +~6 * 268435456 = ~1610612736 +~6 * 134217728 = ~805306368 +~6 * 67108864 = ~402653184 +~5 * 1073741824 = Overflow +~5 * 536870912 = Overflow +~5 * 268435456 = ~1342177280 +~5 * 134217728 = ~671088640 +~5 * 67108864 = ~335544320 +~4 * 1073741824 = Overflow +~4 * 536870912 = ~2147483648 +~4 * 268435456 = ~1073741824 +~4 * 134217728 = ~536870912 +~4 * 67108864 = ~268435456 +~3 * 1073741824 = Overflow +~3 * 536870912 = ~1610612736 +~3 * 268435456 = ~805306368 +~3 * 134217728 = ~402653184 +~3 * 67108864 = ~201326592 +~2 * 1073741824 = ~2147483648 +~2 * 536870912 = ~1073741824 +~2 * 268435456 = ~536870912 +~2 * 134217728 = ~268435456 +~2 * 67108864 = ~134217728 +~1 * 1073741824 = ~1073741824 +~1 * 536870912 = ~536870912 +~1 * 268435456 = ~268435456 +~1 * 134217728 = ~134217728 +~1 * 67108864 = ~67108864 +0 * 1073741824 = 0 +0 * 536870912 = 0 +0 * 268435456 = 0 +0 * 134217728 = 0 +0 * 67108864 = 0 +1 * 1073741824 = 1073741824 +1 * 536870912 = 536870912 +1 * 268435456 = 268435456 +1 * 134217728 = 134217728 +1 * 67108864 = 67108864 +2 * 1073741824 = Overflow +2 * 536870912 = 1073741824 +2 * 268435456 = 536870912 +2 * 134217728 = 268435456 +2 * 67108864 = 134217728 +3 * 1073741824 = Overflow +3 * 536870912 = 1610612736 +3 * 268435456 = 805306368 +3 * 134217728 = 402653184 +3 * 67108864 = 201326592 +4 * 1073741824 = Overflow +4 * 536870912 = Overflow +4 * 268435456 = 1073741824 +4 * 134217728 = 536870912 +4 * 67108864 = 268435456 +5 * 1073741824 = Overflow +5 * 536870912 = Overflow +5 * 268435456 = 1342177280 +5 * 134217728 = 671088640 +5 * 67108864 = 335544320 +6 * 1073741824 = Overflow +6 * 536870912 = Overflow +6 * 268435456 = 1610612736 +6 * 134217728 = 805306368 +6 * 67108864 = 402653184 +7 * 1073741824 = Overflow +7 * 536870912 = Overflow +7 * 268435456 = 1879048192 +7 * 134217728 = 939524096 +7 * 67108864 = 469762048 +8 * 1073741824 = Overflow +8 * 536870912 = Overflow +8 * 268435456 = Overflow +8 * 134217728 = 1073741824 +8 * 67108864 = 536870912 +9 * 1073741824 = Overflow +9 * 536870912 = Overflow +9 * 268435456 = Overflow +9 * 134217728 = 1207959552 +9 * 67108864 = 603979776 +10 * 1073741824 = Overflow +10 * 536870912 = Overflow +10 * 268435456 = Overflow +10 * 134217728 = 1342177280 +10 * 67108864 = 671088640 +11 * 1073741824 = Overflow +11 * 536870912 = Overflow +11 * 268435456 = Overflow +11 * 134217728 = 1476395008 +11 * 67108864 = 738197504 +12 * 1073741824 = Overflow +12 * 536870912 = Overflow +12 * 268435456 = Overflow +12 * 134217728 = 1610612736 +12 * 67108864 = 805306368 +13 * 1073741824 = Overflow +13 * 536870912 = Overflow +13 * 268435456 = Overflow +13 * 134217728 = 1744830464 +13 * 67108864 = 872415232 +14 * 1073741824 = Overflow +14 * 536870912 = Overflow +14 * 268435456 = Overflow +14 * 134217728 = 1879048192 +14 * 67108864 = 939524096 +15 * 1073741824 = Overflow +15 * 536870912 = Overflow +15 * 268435456 = Overflow +15 * 134217728 = 2013265920 +15 * 67108864 = 1006632960 +16 * 1073741824 = Overflow +16 * 536870912 = Overflow +16 * 268435456 = Overflow +16 * 134217728 = Overflow +16 * 67108864 = 1073741824 +17 * 1073741824 = Overflow +17 * 536870912 = Overflow +17 * 268435456 = Overflow +17 * 134217728 = Overflow +17 * 67108864 = 1140850688 +18 * 1073741824 = Overflow +18 * 536870912 = Overflow +18 * 268435456 = Overflow +18 * 134217728 = Overflow +18 * 67108864 = 1207959552 +19 * 1073741824 = Overflow +19 * 536870912 = Overflow +19 * 268435456 = Overflow +19 * 134217728 = Overflow +19 * 67108864 = 1275068416 +20 * 1073741824 = Overflow +20 * 536870912 = Overflow +20 * 268435456 = Overflow +20 * 134217728 = Overflow +20 * 67108864 = 1342177280 +21 * 1073741824 = Overflow +21 * 536870912 = Overflow +21 * 268435456 = Overflow +21 * 134217728 = Overflow +21 * 67108864 = 1409286144 +22 * 1073741824 = Overflow +22 * 536870912 = Overflow +22 * 268435456 = Overflow +22 * 134217728 = Overflow +22 * 67108864 = 1476395008 +23 * 1073741824 = Overflow +23 * 536870912 = Overflow +23 * 268435456 = Overflow +23 * 134217728 = Overflow +23 * 67108864 = 1543503872 +24 * 1073741824 = Overflow +24 * 536870912 = Overflow +24 * 268435456 = Overflow +24 * 134217728 = Overflow +24 * 67108864 = 1610612736 +25 * 1073741824 = Overflow +25 * 536870912 = Overflow +25 * 268435456 = Overflow +25 * 134217728 = Overflow +25 * 67108864 = 1677721600 +26 * 1073741824 = Overflow +26 * 536870912 = Overflow +26 * 268435456 = Overflow +26 * 134217728 = Overflow +26 * 67108864 = 1744830464 +27 * 1073741824 = Overflow +27 * 536870912 = Overflow +27 * 268435456 = Overflow +27 * 134217728 = Overflow +27 * 67108864 = 1811939328 +28 * 1073741824 = Overflow +28 * 536870912 = Overflow +28 * 268435456 = Overflow +28 * 134217728 = Overflow +28 * 67108864 = 1879048192 +29 * 1073741824 = Overflow +29 * 536870912 = Overflow +29 * 268435456 = Overflow +29 * 134217728 = Overflow +29 * 67108864 = 1946157056 +30 * 1073741824 = Overflow +30 * 536870912 = Overflow +30 * 268435456 = Overflow +30 * 134217728 = Overflow +30 * 67108864 = 2013265920 +31 * 1073741824 = Overflow +31 * 536870912 = Overflow +31 * 268435456 = Overflow +31 * 134217728 = Overflow +31 * 67108864 = 2080374784 +32 * 1073741824 = Overflow +32 * 536870912 = Overflow +32 * 268435456 = Overflow +32 * 134217728 = Overflow +32 * 67108864 = Overflow +~32 * ~2147483648 = Overflow +~32 * ~1073741824 = Overflow +~32 * ~536870912 = Overflow +~32 * ~268435456 = Overflow +~32 * ~134217728 = Overflow +~31 * ~2147483648 = Overflow +~31 * ~1073741824 = Overflow +~31 * ~536870912 = Overflow +~31 * ~268435456 = Overflow +~31 * ~134217728 = Overflow +~30 * ~2147483648 = Overflow +~30 * ~1073741824 = Overflow +~30 * ~536870912 = Overflow +~30 * ~268435456 = Overflow +~30 * ~134217728 = Overflow +~29 * ~2147483648 = Overflow +~29 * ~1073741824 = Overflow +~29 * ~536870912 = Overflow +~29 * ~268435456 = Overflow +~29 * ~134217728 = Overflow +~28 * ~2147483648 = Overflow +~28 * ~1073741824 = Overflow +~28 * ~536870912 = Overflow +~28 * ~268435456 = Overflow +~28 * ~134217728 = Overflow +~27 * ~2147483648 = Overflow +~27 * ~1073741824 = Overflow +~27 * ~536870912 = Overflow +~27 * ~268435456 = Overflow +~27 * ~134217728 = Overflow +~26 * ~2147483648 = Overflow +~26 * ~1073741824 = Overflow +~26 * ~536870912 = Overflow +~26 * ~268435456 = Overflow +~26 * ~134217728 = Overflow +~25 * ~2147483648 = Overflow +~25 * ~1073741824 = Overflow +~25 * ~536870912 = Overflow +~25 * ~268435456 = Overflow +~25 * ~134217728 = Overflow +~24 * ~2147483648 = Overflow +~24 * ~1073741824 = Overflow +~24 * ~536870912 = Overflow +~24 * ~268435456 = Overflow +~24 * ~134217728 = Overflow +~23 * ~2147483648 = Overflow +~23 * ~1073741824 = Overflow +~23 * ~536870912 = Overflow +~23 * ~268435456 = Overflow +~23 * ~134217728 = Overflow +~22 * ~2147483648 = Overflow +~22 * ~1073741824 = Overflow +~22 * ~536870912 = Overflow +~22 * ~268435456 = Overflow +~22 * ~134217728 = Overflow +~21 * ~2147483648 = Overflow +~21 * ~1073741824 = Overflow +~21 * ~536870912 = Overflow +~21 * ~268435456 = Overflow +~21 * ~134217728 = Overflow +~20 * ~2147483648 = Overflow +~20 * ~1073741824 = Overflow +~20 * ~536870912 = Overflow +~20 * ~268435456 = Overflow +~20 * ~134217728 = Overflow +~19 * ~2147483648 = Overflow +~19 * ~1073741824 = Overflow +~19 * ~536870912 = Overflow +~19 * ~268435456 = Overflow +~19 * ~134217728 = Overflow +~18 * ~2147483648 = Overflow +~18 * ~1073741824 = Overflow +~18 * ~536870912 = Overflow +~18 * ~268435456 = Overflow +~18 * ~134217728 = Overflow +~17 * ~2147483648 = Overflow +~17 * ~1073741824 = Overflow +~17 * ~536870912 = Overflow +~17 * ~268435456 = Overflow +~17 * ~134217728 = Overflow +~16 * ~2147483648 = Overflow +~16 * ~1073741824 = Overflow +~16 * ~536870912 = Overflow +~16 * ~268435456 = Overflow +~16 * ~134217728 = Overflow +~15 * ~2147483648 = Overflow +~15 * ~1073741824 = Overflow +~15 * ~536870912 = Overflow +~15 * ~268435456 = Overflow +~15 * ~134217728 = 2013265920 +~14 * ~2147483648 = Overflow +~14 * ~1073741824 = Overflow +~14 * ~536870912 = Overflow +~14 * ~268435456 = Overflow +~14 * ~134217728 = 1879048192 +~13 * ~2147483648 = Overflow +~13 * ~1073741824 = Overflow +~13 * ~536870912 = Overflow +~13 * ~268435456 = Overflow +~13 * ~134217728 = 1744830464 +~12 * ~2147483648 = Overflow +~12 * ~1073741824 = Overflow +~12 * ~536870912 = Overflow +~12 * ~268435456 = Overflow +~12 * ~134217728 = 1610612736 +~11 * ~2147483648 = Overflow +~11 * ~1073741824 = Overflow +~11 * ~536870912 = Overflow +~11 * ~268435456 = Overflow +~11 * ~134217728 = 1476395008 +~10 * ~2147483648 = Overflow +~10 * ~1073741824 = Overflow +~10 * ~536870912 = Overflow +~10 * ~268435456 = Overflow +~10 * ~134217728 = 1342177280 +~9 * ~2147483648 = Overflow +~9 * ~1073741824 = Overflow +~9 * ~536870912 = Overflow +~9 * ~268435456 = Overflow +~9 * ~134217728 = 1207959552 +~8 * ~2147483648 = Overflow +~8 * ~1073741824 = Overflow +~8 * ~536870912 = Overflow +~8 * ~268435456 = Overflow +~8 * ~134217728 = 1073741824 +~7 * ~2147483648 = Overflow +~7 * ~1073741824 = Overflow +~7 * ~536870912 = Overflow +~7 * ~268435456 = 1879048192 +~7 * ~134217728 = 939524096 +~6 * ~2147483648 = Overflow +~6 * ~1073741824 = Overflow +~6 * ~536870912 = Overflow +~6 * ~268435456 = 1610612736 +~6 * ~134217728 = 805306368 +~5 * ~2147483648 = Overflow +~5 * ~1073741824 = Overflow +~5 * ~536870912 = Overflow +~5 * ~268435456 = 1342177280 +~5 * ~134217728 = 671088640 +~4 * ~2147483648 = Overflow +~4 * ~1073741824 = Overflow +~4 * ~536870912 = Overflow +~4 * ~268435456 = 1073741824 +~4 * ~134217728 = 536870912 +~3 * ~2147483648 = Overflow +~3 * ~1073741824 = Overflow +~3 * ~536870912 = 1610612736 +~3 * ~268435456 = 805306368 +~3 * ~134217728 = 402653184 +~2 * ~2147483648 = Overflow +~2 * ~1073741824 = Overflow +~2 * ~536870912 = 1073741824 +~2 * ~268435456 = 536870912 +~2 * ~134217728 = 268435456 +~1 * ~2147483648 = Overflow +~1 * ~1073741824 = 1073741824 +~1 * ~536870912 = 536870912 +~1 * ~268435456 = 268435456 +~1 * ~134217728 = 134217728 +0 * ~2147483648 = 0 +0 * ~1073741824 = 0 +0 * ~536870912 = 0 +0 * ~268435456 = 0 +0 * ~134217728 = 0 +1 * ~2147483648 = ~2147483648 +1 * ~1073741824 = ~1073741824 +1 * ~536870912 = ~536870912 +1 * ~268435456 = ~268435456 +1 * ~134217728 = ~134217728 +2 * ~2147483648 = Overflow +2 * ~1073741824 = ~2147483648 +2 * ~536870912 = ~1073741824 +2 * ~268435456 = ~536870912 +2 * ~134217728 = ~268435456 +3 * ~2147483648 = Overflow +3 * ~1073741824 = Overflow +3 * ~536870912 = ~1610612736 +3 * ~268435456 = ~805306368 +3 * ~134217728 = ~402653184 +4 * ~2147483648 = Overflow +4 * ~1073741824 = Overflow +4 * ~536870912 = ~2147483648 +4 * ~268435456 = ~1073741824 +4 * ~134217728 = ~536870912 +5 * ~2147483648 = Overflow +5 * ~1073741824 = Overflow +5 * ~536870912 = Overflow +5 * ~268435456 = ~1342177280 +5 * ~134217728 = ~671088640 +6 * ~2147483648 = Overflow +6 * ~1073741824 = Overflow +6 * ~536870912 = Overflow +6 * ~268435456 = ~1610612736 +6 * ~134217728 = ~805306368 +7 * ~2147483648 = Overflow +7 * ~1073741824 = Overflow +7 * ~536870912 = Overflow +7 * ~268435456 = ~1879048192 +7 * ~134217728 = ~939524096 +8 * ~2147483648 = Overflow +8 * ~1073741824 = Overflow +8 * ~536870912 = Overflow +8 * ~268435456 = ~2147483648 +8 * ~134217728 = ~1073741824 +9 * ~2147483648 = Overflow +9 * ~1073741824 = Overflow +9 * ~536870912 = Overflow +9 * ~268435456 = Overflow +9 * ~134217728 = ~1207959552 +10 * ~2147483648 = Overflow +10 * ~1073741824 = Overflow +10 * ~536870912 = Overflow +10 * ~268435456 = Overflow +10 * ~134217728 = ~1342177280 +11 * ~2147483648 = Overflow +11 * ~1073741824 = Overflow +11 * ~536870912 = Overflow +11 * ~268435456 = Overflow +11 * ~134217728 = ~1476395008 +12 * ~2147483648 = Overflow +12 * ~1073741824 = Overflow +12 * ~536870912 = Overflow +12 * ~268435456 = Overflow +12 * ~134217728 = ~1610612736 +13 * ~2147483648 = Overflow +13 * ~1073741824 = Overflow +13 * ~536870912 = Overflow +13 * ~268435456 = Overflow +13 * ~134217728 = ~1744830464 +14 * ~2147483648 = Overflow +14 * ~1073741824 = Overflow +14 * ~536870912 = Overflow +14 * ~268435456 = Overflow +14 * ~134217728 = ~1879048192 +15 * ~2147483648 = Overflow +15 * ~1073741824 = Overflow +15 * ~536870912 = Overflow +15 * ~268435456 = Overflow +15 * ~134217728 = ~2013265920 +16 * ~2147483648 = Overflow +16 * ~1073741824 = Overflow +16 * ~536870912 = Overflow +16 * ~268435456 = Overflow +16 * ~134217728 = ~2147483648 +17 * ~2147483648 = Overflow +17 * ~1073741824 = Overflow +17 * ~536870912 = Overflow +17 * ~268435456 = Overflow +17 * ~134217728 = Overflow +18 * ~2147483648 = Overflow +18 * ~1073741824 = Overflow +18 * ~536870912 = Overflow +18 * ~268435456 = Overflow +18 * ~134217728 = Overflow +19 * ~2147483648 = Overflow +19 * ~1073741824 = Overflow +19 * ~536870912 = Overflow +19 * ~268435456 = Overflow +19 * ~134217728 = Overflow +20 * ~2147483648 = Overflow +20 * ~1073741824 = Overflow +20 * ~536870912 = Overflow +20 * ~268435456 = Overflow +20 * ~134217728 = Overflow +21 * ~2147483648 = Overflow +21 * ~1073741824 = Overflow +21 * ~536870912 = Overflow +21 * ~268435456 = Overflow +21 * ~134217728 = Overflow +22 * ~2147483648 = Overflow +22 * ~1073741824 = Overflow +22 * ~536870912 = Overflow +22 * ~268435456 = Overflow +22 * ~134217728 = Overflow +23 * ~2147483648 = Overflow +23 * ~1073741824 = Overflow +23 * ~536870912 = Overflow +23 * ~268435456 = Overflow +23 * ~134217728 = Overflow +24 * ~2147483648 = Overflow +24 * ~1073741824 = Overflow +24 * ~536870912 = Overflow +24 * ~268435456 = Overflow +24 * ~134217728 = Overflow +25 * ~2147483648 = Overflow +25 * ~1073741824 = Overflow +25 * ~536870912 = Overflow +25 * ~268435456 = Overflow +25 * ~134217728 = Overflow +26 * ~2147483648 = Overflow +26 * ~1073741824 = Overflow +26 * ~536870912 = Overflow +26 * ~268435456 = Overflow +26 * ~134217728 = Overflow +27 * ~2147483648 = Overflow +27 * ~1073741824 = Overflow +27 * ~536870912 = Overflow +27 * ~268435456 = Overflow +27 * ~134217728 = Overflow +28 * ~2147483648 = Overflow +28 * ~1073741824 = Overflow +28 * ~536870912 = Overflow +28 * ~268435456 = Overflow +28 * ~134217728 = Overflow +29 * ~2147483648 = Overflow +29 * ~1073741824 = Overflow +29 * ~536870912 = Overflow +29 * ~268435456 = Overflow +29 * ~134217728 = Overflow +30 * ~2147483648 = Overflow +30 * ~1073741824 = Overflow +30 * ~536870912 = Overflow +30 * ~268435456 = Overflow +30 * ~134217728 = Overflow +31 * ~2147483648 = Overflow +31 * ~1073741824 = Overflow +31 * ~536870912 = Overflow +31 * ~268435456 = Overflow +31 * ~134217728 = Overflow +32 * ~2147483648 = Overflow +32 * ~1073741824 = Overflow +32 * ~536870912 = Overflow +32 * ~268435456 = Overflow +32 * ~134217728 = Overflow +~2147483648 * 1 = ~2147483648 +~2147483648 * 2 = Overflow +~2147483648 * 4 = Overflow +~2147483648 * 8 = Overflow +~2147483648 * 16 = Overflow +~1073741824 * 1 = ~1073741824 +~1073741824 * 2 = ~2147483648 +~1073741824 * 4 = Overflow +~1073741824 * 8 = Overflow +~1073741824 * 16 = Overflow +~536870912 * 1 = ~536870912 +~536870912 * 2 = ~1073741824 +~536870912 * 4 = ~2147483648 +~536870912 * 8 = Overflow +~536870912 * 16 = Overflow +~268435456 * 1 = ~268435456 +~268435456 * 2 = ~536870912 +~268435456 * 4 = ~1073741824 +~268435456 * 8 = ~2147483648 +~268435456 * 16 = Overflow +~134217728 * 1 = ~134217728 +~134217728 * 2 = ~268435456 +~134217728 * 4 = ~536870912 +~134217728 * 8 = ~1073741824 +~134217728 * 16 = ~2147483648 +~67108864 * 1 = ~67108864 +~67108864 * 2 = ~134217728 +~67108864 * 4 = ~268435456 +~67108864 * 8 = ~536870912 +~67108864 * 16 = ~1073741824 +~4 * 1 = ~4 +~4 * 2 = ~8 +~4 * 4 = ~16 +~4 * 8 = ~32 +~4 * 16 = ~64 +~3 * 1 = ~3 +~3 * 2 = ~6 +~3 * 4 = ~12 +~3 * 8 = ~24 +~3 * 16 = ~48 +~2 * 1 = ~2 +~2 * 2 = ~4 +~2 * 4 = ~8 +~2 * 8 = ~16 +~2 * 16 = ~32 +~1 * 1 = ~1 +~1 * 2 = ~2 +~1 * 4 = ~4 +~1 * 8 = ~8 +~1 * 16 = ~16 +0 * 1 = 0 +0 * 2 = 0 +0 * 4 = 0 +0 * 8 = 0 +0 * 16 = 0 +1 * 1 = 1 +1 * 2 = 2 +1 * 4 = 4 +1 * 8 = 8 +1 * 16 = 16 +2 * 1 = 2 +2 * 2 = 4 +2 * 4 = 8 +2 * 8 = 16 +2 * 16 = 32 +3 * 1 = 3 +3 * 2 = 6 +3 * 4 = 12 +3 * 8 = 24 +3 * 16 = 48 +4 * 1 = 4 +4 * 2 = 8 +4 * 4 = 16 +4 * 8 = 32 +4 * 16 = 64 +33554432 * 1 = 33554432 +33554432 * 2 = 67108864 +33554432 * 4 = 134217728 +33554432 * 8 = 268435456 +33554432 * 16 = 536870912 +67108864 * 1 = 67108864 +67108864 * 2 = 134217728 +67108864 * 4 = 268435456 +67108864 * 8 = 536870912 +67108864 * 16 = 1073741824 +134217728 * 1 = 134217728 +134217728 * 2 = 268435456 +134217728 * 4 = 536870912 +134217728 * 8 = 1073741824 +134217728 * 16 = Overflow +268435456 * 1 = 268435456 +268435456 * 2 = 536870912 +268435456 * 4 = 1073741824 +268435456 * 8 = Overflow +268435456 * 16 = Overflow +536870912 * 1 = 536870912 +536870912 * 2 = 1073741824 +536870912 * 4 = Overflow +536870912 * 8 = Overflow +536870912 * 16 = Overflow +1073741824 * 1 = 1073741824 +1073741824 * 2 = Overflow +1073741824 * 4 = Overflow +1073741824 * 8 = Overflow +1073741824 * 16 = Overflow +~2147483648 * ~1 = Overflow +~2147483648 * ~2 = Overflow +~2147483648 * ~4 = Overflow +~2147483648 * ~8 = Overflow +~2147483648 * ~16 = Overflow +~1073741824 * ~1 = 1073741824 +~1073741824 * ~2 = Overflow +~1073741824 * ~4 = Overflow +~1073741824 * ~8 = Overflow +~1073741824 * ~16 = Overflow +~536870912 * ~1 = 536870912 +~536870912 * ~2 = 1073741824 +~536870912 * ~4 = Overflow +~536870912 * ~8 = Overflow +~536870912 * ~16 = Overflow +~268435456 * ~1 = 268435456 +~268435456 * ~2 = 536870912 +~268435456 * ~4 = 1073741824 +~268435456 * ~8 = Overflow +~268435456 * ~16 = Overflow +~134217728 * ~1 = 134217728 +~134217728 * ~2 = 268435456 +~134217728 * ~4 = 536870912 +~134217728 * ~8 = 1073741824 +~134217728 * ~16 = Overflow +~67108864 * ~1 = 67108864 +~67108864 * ~2 = 134217728 +~67108864 * ~4 = 268435456 +~67108864 * ~8 = 536870912 +~67108864 * ~16 = 1073741824 +~4 * ~1 = 4 +~4 * ~2 = 8 +~4 * ~4 = 16 +~4 * ~8 = 32 +~4 * ~16 = 64 +~3 * ~1 = 3 +~3 * ~2 = 6 +~3 * ~4 = 12 +~3 * ~8 = 24 +~3 * ~16 = 48 +~2 * ~1 = 2 +~2 * ~2 = 4 +~2 * ~4 = 8 +~2 * ~8 = 16 +~2 * ~16 = 32 +~1 * ~1 = 1 +~1 * ~2 = 2 +~1 * ~4 = 4 +~1 * ~8 = 8 +~1 * ~16 = 16 +0 * ~1 = 0 +0 * ~2 = 0 +0 * ~4 = 0 +0 * ~8 = 0 +0 * ~16 = 0 +1 * ~1 = ~1 +1 * ~2 = ~2 +1 * ~4 = ~4 +1 * ~8 = ~8 +1 * ~16 = ~16 +2 * ~1 = ~2 +2 * ~2 = ~4 +2 * ~4 = ~8 +2 * ~8 = ~16 +2 * ~16 = ~32 +3 * ~1 = ~3 +3 * ~2 = ~6 +3 * ~4 = ~12 +3 * ~8 = ~24 +3 * ~16 = ~48 +4 * ~1 = ~4 +4 * ~2 = ~8 +4 * ~4 = ~16 +4 * ~8 = ~32 +4 * ~16 = ~64 +33554432 * ~1 = ~33554432 +33554432 * ~2 = ~67108864 +33554432 * ~4 = ~134217728 +33554432 * ~8 = ~268435456 +33554432 * ~16 = ~536870912 +67108864 * ~1 = ~67108864 +67108864 * ~2 = ~134217728 +67108864 * ~4 = ~268435456 +67108864 * ~8 = ~536870912 +67108864 * ~16 = ~1073741824 +134217728 * ~1 = ~134217728 +134217728 * ~2 = ~268435456 +134217728 * ~4 = ~536870912 +134217728 * ~8 = ~1073741824 +134217728 * ~16 = ~2147483648 +268435456 * ~1 = ~268435456 +268435456 * ~2 = ~536870912 +268435456 * ~4 = ~1073741824 +268435456 * ~8 = ~2147483648 +268435456 * ~16 = Overflow +536870912 * ~1 = ~536870912 +536870912 * ~2 = ~1073741824 +536870912 * ~4 = ~2147483648 +536870912 * ~8 = Overflow +536870912 * ~16 = Overflow +1073741824 * ~1 = ~1073741824 +1073741824 * ~2 = ~2147483648 +1073741824 * ~4 = Overflow +1073741824 * ~8 = Overflow +1073741824 * ~16 = Overflow +~32 * 4611686018427387904 = Overflow +~32 * 2305843009213693952 = Overflow +~32 * 1152921504606846976 = Overflow +~32 * 576460752303423488 = Overflow +~32 * 288230376151711744 = ~9223372036854775808 +~31 * 4611686018427387904 = Overflow +~31 * 2305843009213693952 = Overflow +~31 * 1152921504606846976 = Overflow +~31 * 576460752303423488 = Overflow +~31 * 288230376151711744 = ~8935141660703064064 +~30 * 4611686018427387904 = Overflow +~30 * 2305843009213693952 = Overflow +~30 * 1152921504606846976 = Overflow +~30 * 576460752303423488 = Overflow +~30 * 288230376151711744 = ~8646911284551352320 +~29 * 4611686018427387904 = Overflow +~29 * 2305843009213693952 = Overflow +~29 * 1152921504606846976 = Overflow +~29 * 576460752303423488 = Overflow +~29 * 288230376151711744 = ~8358680908399640576 +~28 * 4611686018427387904 = Overflow +~28 * 2305843009213693952 = Overflow +~28 * 1152921504606846976 = Overflow +~28 * 576460752303423488 = Overflow +~28 * 288230376151711744 = ~8070450532247928832 +~27 * 4611686018427387904 = Overflow +~27 * 2305843009213693952 = Overflow +~27 * 1152921504606846976 = Overflow +~27 * 576460752303423488 = Overflow +~27 * 288230376151711744 = ~7782220156096217088 +~26 * 4611686018427387904 = Overflow +~26 * 2305843009213693952 = Overflow +~26 * 1152921504606846976 = Overflow +~26 * 576460752303423488 = Overflow +~26 * 288230376151711744 = ~7493989779944505344 +~25 * 4611686018427387904 = Overflow +~25 * 2305843009213693952 = Overflow +~25 * 1152921504606846976 = Overflow +~25 * 576460752303423488 = Overflow +~25 * 288230376151711744 = ~7205759403792793600 +~24 * 4611686018427387904 = Overflow +~24 * 2305843009213693952 = Overflow +~24 * 1152921504606846976 = Overflow +~24 * 576460752303423488 = Overflow +~24 * 288230376151711744 = ~6917529027641081856 +~23 * 4611686018427387904 = Overflow +~23 * 2305843009213693952 = Overflow +~23 * 1152921504606846976 = Overflow +~23 * 576460752303423488 = Overflow +~23 * 288230376151711744 = ~6629298651489370112 +~22 * 4611686018427387904 = Overflow +~22 * 2305843009213693952 = Overflow +~22 * 1152921504606846976 = Overflow +~22 * 576460752303423488 = Overflow +~22 * 288230376151711744 = ~6341068275337658368 +~21 * 4611686018427387904 = Overflow +~21 * 2305843009213693952 = Overflow +~21 * 1152921504606846976 = Overflow +~21 * 576460752303423488 = Overflow +~21 * 288230376151711744 = ~6052837899185946624 +~20 * 4611686018427387904 = Overflow +~20 * 2305843009213693952 = Overflow +~20 * 1152921504606846976 = Overflow +~20 * 576460752303423488 = Overflow +~20 * 288230376151711744 = ~5764607523034234880 +~19 * 4611686018427387904 = Overflow +~19 * 2305843009213693952 = Overflow +~19 * 1152921504606846976 = Overflow +~19 * 576460752303423488 = Overflow +~19 * 288230376151711744 = ~5476377146882523136 +~18 * 4611686018427387904 = Overflow +~18 * 2305843009213693952 = Overflow +~18 * 1152921504606846976 = Overflow +~18 * 576460752303423488 = Overflow +~18 * 288230376151711744 = ~5188146770730811392 +~17 * 4611686018427387904 = Overflow +~17 * 2305843009213693952 = Overflow +~17 * 1152921504606846976 = Overflow +~17 * 576460752303423488 = Overflow +~17 * 288230376151711744 = ~4899916394579099648 +~16 * 4611686018427387904 = Overflow +~16 * 2305843009213693952 = Overflow +~16 * 1152921504606846976 = Overflow +~16 * 576460752303423488 = ~9223372036854775808 +~16 * 288230376151711744 = ~4611686018427387904 +~15 * 4611686018427387904 = Overflow +~15 * 2305843009213693952 = Overflow +~15 * 1152921504606846976 = Overflow +~15 * 576460752303423488 = ~8646911284551352320 +~15 * 288230376151711744 = ~4323455642275676160 +~14 * 4611686018427387904 = Overflow +~14 * 2305843009213693952 = Overflow +~14 * 1152921504606846976 = Overflow +~14 * 576460752303423488 = ~8070450532247928832 +~14 * 288230376151711744 = ~4035225266123964416 +~13 * 4611686018427387904 = Overflow +~13 * 2305843009213693952 = Overflow +~13 * 1152921504606846976 = Overflow +~13 * 576460752303423488 = ~7493989779944505344 +~13 * 288230376151711744 = ~3746994889972252672 +~12 * 4611686018427387904 = Overflow +~12 * 2305843009213693952 = Overflow +~12 * 1152921504606846976 = Overflow +~12 * 576460752303423488 = ~6917529027641081856 +~12 * 288230376151711744 = ~3458764513820540928 +~11 * 4611686018427387904 = Overflow +~11 * 2305843009213693952 = Overflow +~11 * 1152921504606846976 = Overflow +~11 * 576460752303423488 = ~6341068275337658368 +~11 * 288230376151711744 = ~3170534137668829184 +~10 * 4611686018427387904 = Overflow +~10 * 2305843009213693952 = Overflow +~10 * 1152921504606846976 = Overflow +~10 * 576460752303423488 = ~5764607523034234880 +~10 * 288230376151711744 = ~2882303761517117440 +~9 * 4611686018427387904 = Overflow +~9 * 2305843009213693952 = Overflow +~9 * 1152921504606846976 = Overflow +~9 * 576460752303423488 = ~5188146770730811392 +~9 * 288230376151711744 = ~2594073385365405696 +~8 * 4611686018427387904 = Overflow +~8 * 2305843009213693952 = Overflow +~8 * 1152921504606846976 = ~9223372036854775808 +~8 * 576460752303423488 = ~4611686018427387904 +~8 * 288230376151711744 = ~2305843009213693952 +~7 * 4611686018427387904 = Overflow +~7 * 2305843009213693952 = Overflow +~7 * 1152921504606846976 = ~8070450532247928832 +~7 * 576460752303423488 = ~4035225266123964416 +~7 * 288230376151711744 = ~2017612633061982208 +~6 * 4611686018427387904 = Overflow +~6 * 2305843009213693952 = Overflow +~6 * 1152921504606846976 = ~6917529027641081856 +~6 * 576460752303423488 = ~3458764513820540928 +~6 * 288230376151711744 = ~1729382256910270464 +~5 * 4611686018427387904 = Overflow +~5 * 2305843009213693952 = Overflow +~5 * 1152921504606846976 = ~5764607523034234880 +~5 * 576460752303423488 = ~2882303761517117440 +~5 * 288230376151711744 = ~1441151880758558720 +~4 * 4611686018427387904 = Overflow +~4 * 2305843009213693952 = ~9223372036854775808 +~4 * 1152921504606846976 = ~4611686018427387904 +~4 * 576460752303423488 = ~2305843009213693952 +~4 * 288230376151711744 = ~1152921504606846976 +~3 * 4611686018427387904 = Overflow +~3 * 2305843009213693952 = ~6917529027641081856 +~3 * 1152921504606846976 = ~3458764513820540928 +~3 * 576460752303423488 = ~1729382256910270464 +~3 * 288230376151711744 = ~864691128455135232 +~2 * 4611686018427387904 = ~9223372036854775808 +~2 * 2305843009213693952 = ~4611686018427387904 +~2 * 1152921504606846976 = ~2305843009213693952 +~2 * 576460752303423488 = ~1152921504606846976 +~2 * 288230376151711744 = ~576460752303423488 +~1 * 4611686018427387904 = ~4611686018427387904 +~1 * 2305843009213693952 = ~2305843009213693952 +~1 * 1152921504606846976 = ~1152921504606846976 +~1 * 576460752303423488 = ~576460752303423488 +~1 * 288230376151711744 = ~288230376151711744 +0 * 4611686018427387904 = 0 +0 * 2305843009213693952 = 0 +0 * 1152921504606846976 = 0 +0 * 576460752303423488 = 0 +0 * 288230376151711744 = 0 +1 * 4611686018427387904 = 4611686018427387904 +1 * 2305843009213693952 = 2305843009213693952 +1 * 1152921504606846976 = 1152921504606846976 +1 * 576460752303423488 = 576460752303423488 +1 * 288230376151711744 = 288230376151711744 +2 * 4611686018427387904 = Overflow +2 * 2305843009213693952 = 4611686018427387904 +2 * 1152921504606846976 = 2305843009213693952 +2 * 576460752303423488 = 1152921504606846976 +2 * 288230376151711744 = 576460752303423488 +3 * 4611686018427387904 = Overflow +3 * 2305843009213693952 = 6917529027641081856 +3 * 1152921504606846976 = 3458764513820540928 +3 * 576460752303423488 = 1729382256910270464 +3 * 288230376151711744 = 864691128455135232 +4 * 4611686018427387904 = Overflow +4 * 2305843009213693952 = Overflow +4 * 1152921504606846976 = 4611686018427387904 +4 * 576460752303423488 = 2305843009213693952 +4 * 288230376151711744 = 1152921504606846976 +5 * 4611686018427387904 = Overflow +5 * 2305843009213693952 = Overflow +5 * 1152921504606846976 = 5764607523034234880 +5 * 576460752303423488 = 2882303761517117440 +5 * 288230376151711744 = 1441151880758558720 +6 * 4611686018427387904 = Overflow +6 * 2305843009213693952 = Overflow +6 * 1152921504606846976 = 6917529027641081856 +6 * 576460752303423488 = 3458764513820540928 +6 * 288230376151711744 = 1729382256910270464 +7 * 4611686018427387904 = Overflow +7 * 2305843009213693952 = Overflow +7 * 1152921504606846976 = 8070450532247928832 +7 * 576460752303423488 = 4035225266123964416 +7 * 288230376151711744 = 2017612633061982208 +8 * 4611686018427387904 = Overflow +8 * 2305843009213693952 = Overflow +8 * 1152921504606846976 = Overflow +8 * 576460752303423488 = 4611686018427387904 +8 * 288230376151711744 = 2305843009213693952 +9 * 4611686018427387904 = Overflow +9 * 2305843009213693952 = Overflow +9 * 1152921504606846976 = Overflow +9 * 576460752303423488 = 5188146770730811392 +9 * 288230376151711744 = 2594073385365405696 +10 * 4611686018427387904 = Overflow +10 * 2305843009213693952 = Overflow +10 * 1152921504606846976 = Overflow +10 * 576460752303423488 = 5764607523034234880 +10 * 288230376151711744 = 2882303761517117440 +11 * 4611686018427387904 = Overflow +11 * 2305843009213693952 = Overflow +11 * 1152921504606846976 = Overflow +11 * 576460752303423488 = 6341068275337658368 +11 * 288230376151711744 = 3170534137668829184 +12 * 4611686018427387904 = Overflow +12 * 2305843009213693952 = Overflow +12 * 1152921504606846976 = Overflow +12 * 576460752303423488 = 6917529027641081856 +12 * 288230376151711744 = 3458764513820540928 +13 * 4611686018427387904 = Overflow +13 * 2305843009213693952 = Overflow +13 * 1152921504606846976 = Overflow +13 * 576460752303423488 = 7493989779944505344 +13 * 288230376151711744 = 3746994889972252672 +14 * 4611686018427387904 = Overflow +14 * 2305843009213693952 = Overflow +14 * 1152921504606846976 = Overflow +14 * 576460752303423488 = 8070450532247928832 +14 * 288230376151711744 = 4035225266123964416 +15 * 4611686018427387904 = Overflow +15 * 2305843009213693952 = Overflow +15 * 1152921504606846976 = Overflow +15 * 576460752303423488 = 8646911284551352320 +15 * 288230376151711744 = 4323455642275676160 +16 * 4611686018427387904 = Overflow +16 * 2305843009213693952 = Overflow +16 * 1152921504606846976 = Overflow +16 * 576460752303423488 = Overflow +16 * 288230376151711744 = 4611686018427387904 +17 * 4611686018427387904 = Overflow +17 * 2305843009213693952 = Overflow +17 * 1152921504606846976 = Overflow +17 * 576460752303423488 = Overflow +17 * 288230376151711744 = 4899916394579099648 +18 * 4611686018427387904 = Overflow +18 * 2305843009213693952 = Overflow +18 * 1152921504606846976 = Overflow +18 * 576460752303423488 = Overflow +18 * 288230376151711744 = 5188146770730811392 +19 * 4611686018427387904 = Overflow +19 * 2305843009213693952 = Overflow +19 * 1152921504606846976 = Overflow +19 * 576460752303423488 = Overflow +19 * 288230376151711744 = 5476377146882523136 +20 * 4611686018427387904 = Overflow +20 * 2305843009213693952 = Overflow +20 * 1152921504606846976 = Overflow +20 * 576460752303423488 = Overflow +20 * 288230376151711744 = 5764607523034234880 +21 * 4611686018427387904 = Overflow +21 * 2305843009213693952 = Overflow +21 * 1152921504606846976 = Overflow +21 * 576460752303423488 = Overflow +21 * 288230376151711744 = 6052837899185946624 +22 * 4611686018427387904 = Overflow +22 * 2305843009213693952 = Overflow +22 * 1152921504606846976 = Overflow +22 * 576460752303423488 = Overflow +22 * 288230376151711744 = 6341068275337658368 +23 * 4611686018427387904 = Overflow +23 * 2305843009213693952 = Overflow +23 * 1152921504606846976 = Overflow +23 * 576460752303423488 = Overflow +23 * 288230376151711744 = 6629298651489370112 +24 * 4611686018427387904 = Overflow +24 * 2305843009213693952 = Overflow +24 * 1152921504606846976 = Overflow +24 * 576460752303423488 = Overflow +24 * 288230376151711744 = 6917529027641081856 +25 * 4611686018427387904 = Overflow +25 * 2305843009213693952 = Overflow +25 * 1152921504606846976 = Overflow +25 * 576460752303423488 = Overflow +25 * 288230376151711744 = 7205759403792793600 +26 * 4611686018427387904 = Overflow +26 * 2305843009213693952 = Overflow +26 * 1152921504606846976 = Overflow +26 * 576460752303423488 = Overflow +26 * 288230376151711744 = 7493989779944505344 +27 * 4611686018427387904 = Overflow +27 * 2305843009213693952 = Overflow +27 * 1152921504606846976 = Overflow +27 * 576460752303423488 = Overflow +27 * 288230376151711744 = 7782220156096217088 +28 * 4611686018427387904 = Overflow +28 * 2305843009213693952 = Overflow +28 * 1152921504606846976 = Overflow +28 * 576460752303423488 = Overflow +28 * 288230376151711744 = 8070450532247928832 +29 * 4611686018427387904 = Overflow +29 * 2305843009213693952 = Overflow +29 * 1152921504606846976 = Overflow +29 * 576460752303423488 = Overflow +29 * 288230376151711744 = 8358680908399640576 +30 * 4611686018427387904 = Overflow +30 * 2305843009213693952 = Overflow +30 * 1152921504606846976 = Overflow +30 * 576460752303423488 = Overflow +30 * 288230376151711744 = 8646911284551352320 +31 * 4611686018427387904 = Overflow +31 * 2305843009213693952 = Overflow +31 * 1152921504606846976 = Overflow +31 * 576460752303423488 = Overflow +31 * 288230376151711744 = 8935141660703064064 +32 * 4611686018427387904 = Overflow +32 * 2305843009213693952 = Overflow +32 * 1152921504606846976 = Overflow +32 * 576460752303423488 = Overflow +32 * 288230376151711744 = Overflow +~32 * ~9223372036854775808 = Overflow +~32 * ~4611686018427387904 = Overflow +~32 * ~2305843009213693952 = Overflow +~32 * ~1152921504606846976 = Overflow +~32 * ~576460752303423488 = Overflow +~31 * ~9223372036854775808 = Overflow +~31 * ~4611686018427387904 = Overflow +~31 * ~2305843009213693952 = Overflow +~31 * ~1152921504606846976 = Overflow +~31 * ~576460752303423488 = Overflow +~30 * ~9223372036854775808 = Overflow +~30 * ~4611686018427387904 = Overflow +~30 * ~2305843009213693952 = Overflow +~30 * ~1152921504606846976 = Overflow +~30 * ~576460752303423488 = Overflow +~29 * ~9223372036854775808 = Overflow +~29 * ~4611686018427387904 = Overflow +~29 * ~2305843009213693952 = Overflow +~29 * ~1152921504606846976 = Overflow +~29 * ~576460752303423488 = Overflow +~28 * ~9223372036854775808 = Overflow +~28 * ~4611686018427387904 = Overflow +~28 * ~2305843009213693952 = Overflow +~28 * ~1152921504606846976 = Overflow +~28 * ~576460752303423488 = Overflow +~27 * ~9223372036854775808 = Overflow +~27 * ~4611686018427387904 = Overflow +~27 * ~2305843009213693952 = Overflow +~27 * ~1152921504606846976 = Overflow +~27 * ~576460752303423488 = Overflow +~26 * ~9223372036854775808 = Overflow +~26 * ~4611686018427387904 = Overflow +~26 * ~2305843009213693952 = Overflow +~26 * ~1152921504606846976 = Overflow +~26 * ~576460752303423488 = Overflow +~25 * ~9223372036854775808 = Overflow +~25 * ~4611686018427387904 = Overflow +~25 * ~2305843009213693952 = Overflow +~25 * ~1152921504606846976 = Overflow +~25 * ~576460752303423488 = Overflow +~24 * ~9223372036854775808 = Overflow +~24 * ~4611686018427387904 = Overflow +~24 * ~2305843009213693952 = Overflow +~24 * ~1152921504606846976 = Overflow +~24 * ~576460752303423488 = Overflow +~23 * ~9223372036854775808 = Overflow +~23 * ~4611686018427387904 = Overflow +~23 * ~2305843009213693952 = Overflow +~23 * ~1152921504606846976 = Overflow +~23 * ~576460752303423488 = Overflow +~22 * ~9223372036854775808 = Overflow +~22 * ~4611686018427387904 = Overflow +~22 * ~2305843009213693952 = Overflow +~22 * ~1152921504606846976 = Overflow +~22 * ~576460752303423488 = Overflow +~21 * ~9223372036854775808 = Overflow +~21 * ~4611686018427387904 = Overflow +~21 * ~2305843009213693952 = Overflow +~21 * ~1152921504606846976 = Overflow +~21 * ~576460752303423488 = Overflow +~20 * ~9223372036854775808 = Overflow +~20 * ~4611686018427387904 = Overflow +~20 * ~2305843009213693952 = Overflow +~20 * ~1152921504606846976 = Overflow +~20 * ~576460752303423488 = Overflow +~19 * ~9223372036854775808 = Overflow +~19 * ~4611686018427387904 = Overflow +~19 * ~2305843009213693952 = Overflow +~19 * ~1152921504606846976 = Overflow +~19 * ~576460752303423488 = Overflow +~18 * ~9223372036854775808 = Overflow +~18 * ~4611686018427387904 = Overflow +~18 * ~2305843009213693952 = Overflow +~18 * ~1152921504606846976 = Overflow +~18 * ~576460752303423488 = Overflow +~17 * ~9223372036854775808 = Overflow +~17 * ~4611686018427387904 = Overflow +~17 * ~2305843009213693952 = Overflow +~17 * ~1152921504606846976 = Overflow +~17 * ~576460752303423488 = Overflow +~16 * ~9223372036854775808 = Overflow +~16 * ~4611686018427387904 = Overflow +~16 * ~2305843009213693952 = Overflow +~16 * ~1152921504606846976 = Overflow +~16 * ~576460752303423488 = Overflow +~15 * ~9223372036854775808 = Overflow +~15 * ~4611686018427387904 = Overflow +~15 * ~2305843009213693952 = Overflow +~15 * ~1152921504606846976 = Overflow +~15 * ~576460752303423488 = 8646911284551352320 +~14 * ~9223372036854775808 = Overflow +~14 * ~4611686018427387904 = Overflow +~14 * ~2305843009213693952 = Overflow +~14 * ~1152921504606846976 = Overflow +~14 * ~576460752303423488 = 8070450532247928832 +~13 * ~9223372036854775808 = Overflow +~13 * ~4611686018427387904 = Overflow +~13 * ~2305843009213693952 = Overflow +~13 * ~1152921504606846976 = Overflow +~13 * ~576460752303423488 = 7493989779944505344 +~12 * ~9223372036854775808 = Overflow +~12 * ~4611686018427387904 = Overflow +~12 * ~2305843009213693952 = Overflow +~12 * ~1152921504606846976 = Overflow +~12 * ~576460752303423488 = 6917529027641081856 +~11 * ~9223372036854775808 = Overflow +~11 * ~4611686018427387904 = Overflow +~11 * ~2305843009213693952 = Overflow +~11 * ~1152921504606846976 = Overflow +~11 * ~576460752303423488 = 6341068275337658368 +~10 * ~9223372036854775808 = Overflow +~10 * ~4611686018427387904 = Overflow +~10 * ~2305843009213693952 = Overflow +~10 * ~1152921504606846976 = Overflow +~10 * ~576460752303423488 = 5764607523034234880 +~9 * ~9223372036854775808 = Overflow +~9 * ~4611686018427387904 = Overflow +~9 * ~2305843009213693952 = Overflow +~9 * ~1152921504606846976 = Overflow +~9 * ~576460752303423488 = 5188146770730811392 +~8 * ~9223372036854775808 = Overflow +~8 * ~4611686018427387904 = Overflow +~8 * ~2305843009213693952 = Overflow +~8 * ~1152921504606846976 = Overflow +~8 * ~576460752303423488 = 4611686018427387904 +~7 * ~9223372036854775808 = Overflow +~7 * ~4611686018427387904 = Overflow +~7 * ~2305843009213693952 = Overflow +~7 * ~1152921504606846976 = 8070450532247928832 +~7 * ~576460752303423488 = 4035225266123964416 +~6 * ~9223372036854775808 = Overflow +~6 * ~4611686018427387904 = Overflow +~6 * ~2305843009213693952 = Overflow +~6 * ~1152921504606846976 = 6917529027641081856 +~6 * ~576460752303423488 = 3458764513820540928 +~5 * ~9223372036854775808 = Overflow +~5 * ~4611686018427387904 = Overflow +~5 * ~2305843009213693952 = Overflow +~5 * ~1152921504606846976 = 5764607523034234880 +~5 * ~576460752303423488 = 2882303761517117440 +~4 * ~9223372036854775808 = Overflow +~4 * ~4611686018427387904 = Overflow +~4 * ~2305843009213693952 = Overflow +~4 * ~1152921504606846976 = 4611686018427387904 +~4 * ~576460752303423488 = 2305843009213693952 +~3 * ~9223372036854775808 = Overflow +~3 * ~4611686018427387904 = Overflow +~3 * ~2305843009213693952 = 6917529027641081856 +~3 * ~1152921504606846976 = 3458764513820540928 +~3 * ~576460752303423488 = 1729382256910270464 +~2 * ~9223372036854775808 = Overflow +~2 * ~4611686018427387904 = Overflow +~2 * ~2305843009213693952 = 4611686018427387904 +~2 * ~1152921504606846976 = 2305843009213693952 +~2 * ~576460752303423488 = 1152921504606846976 +~1 * ~9223372036854775808 = Overflow +~1 * ~4611686018427387904 = 4611686018427387904 +~1 * ~2305843009213693952 = 2305843009213693952 +~1 * ~1152921504606846976 = 1152921504606846976 +~1 * ~576460752303423488 = 576460752303423488 +0 * ~9223372036854775808 = 0 +0 * ~4611686018427387904 = 0 +0 * ~2305843009213693952 = 0 +0 * ~1152921504606846976 = 0 +0 * ~576460752303423488 = 0 +1 * ~9223372036854775808 = ~9223372036854775808 +1 * ~4611686018427387904 = ~4611686018427387904 +1 * ~2305843009213693952 = ~2305843009213693952 +1 * ~1152921504606846976 = ~1152921504606846976 +1 * ~576460752303423488 = ~576460752303423488 +2 * ~9223372036854775808 = Overflow +2 * ~4611686018427387904 = ~9223372036854775808 +2 * ~2305843009213693952 = ~4611686018427387904 +2 * ~1152921504606846976 = ~2305843009213693952 +2 * ~576460752303423488 = ~1152921504606846976 +3 * ~9223372036854775808 = Overflow +3 * ~4611686018427387904 = Overflow +3 * ~2305843009213693952 = ~6917529027641081856 +3 * ~1152921504606846976 = ~3458764513820540928 +3 * ~576460752303423488 = ~1729382256910270464 +4 * ~9223372036854775808 = Overflow +4 * ~4611686018427387904 = Overflow +4 * ~2305843009213693952 = ~9223372036854775808 +4 * ~1152921504606846976 = ~4611686018427387904 +4 * ~576460752303423488 = ~2305843009213693952 +5 * ~9223372036854775808 = Overflow +5 * ~4611686018427387904 = Overflow +5 * ~2305843009213693952 = Overflow +5 * ~1152921504606846976 = ~5764607523034234880 +5 * ~576460752303423488 = ~2882303761517117440 +6 * ~9223372036854775808 = Overflow +6 * ~4611686018427387904 = Overflow +6 * ~2305843009213693952 = Overflow +6 * ~1152921504606846976 = ~6917529027641081856 +6 * ~576460752303423488 = ~3458764513820540928 +7 * ~9223372036854775808 = Overflow +7 * ~4611686018427387904 = Overflow +7 * ~2305843009213693952 = Overflow +7 * ~1152921504606846976 = ~8070450532247928832 +7 * ~576460752303423488 = ~4035225266123964416 +8 * ~9223372036854775808 = Overflow +8 * ~4611686018427387904 = Overflow +8 * ~2305843009213693952 = Overflow +8 * ~1152921504606846976 = ~9223372036854775808 +8 * ~576460752303423488 = ~4611686018427387904 +9 * ~9223372036854775808 = Overflow +9 * ~4611686018427387904 = Overflow +9 * ~2305843009213693952 = Overflow +9 * ~1152921504606846976 = Overflow +9 * ~576460752303423488 = ~5188146770730811392 +10 * ~9223372036854775808 = Overflow +10 * ~4611686018427387904 = Overflow +10 * ~2305843009213693952 = Overflow +10 * ~1152921504606846976 = Overflow +10 * ~576460752303423488 = ~5764607523034234880 +11 * ~9223372036854775808 = Overflow +11 * ~4611686018427387904 = Overflow +11 * ~2305843009213693952 = Overflow +11 * ~1152921504606846976 = Overflow +11 * ~576460752303423488 = ~6341068275337658368 +12 * ~9223372036854775808 = Overflow +12 * ~4611686018427387904 = Overflow +12 * ~2305843009213693952 = Overflow +12 * ~1152921504606846976 = Overflow +12 * ~576460752303423488 = ~6917529027641081856 +13 * ~9223372036854775808 = Overflow +13 * ~4611686018427387904 = Overflow +13 * ~2305843009213693952 = Overflow +13 * ~1152921504606846976 = Overflow +13 * ~576460752303423488 = ~7493989779944505344 +14 * ~9223372036854775808 = Overflow +14 * ~4611686018427387904 = Overflow +14 * ~2305843009213693952 = Overflow +14 * ~1152921504606846976 = Overflow +14 * ~576460752303423488 = ~8070450532247928832 +15 * ~9223372036854775808 = Overflow +15 * ~4611686018427387904 = Overflow +15 * ~2305843009213693952 = Overflow +15 * ~1152921504606846976 = Overflow +15 * ~576460752303423488 = ~8646911284551352320 +16 * ~9223372036854775808 = Overflow +16 * ~4611686018427387904 = Overflow +16 * ~2305843009213693952 = Overflow +16 * ~1152921504606846976 = Overflow +16 * ~576460752303423488 = ~9223372036854775808 +17 * ~9223372036854775808 = Overflow +17 * ~4611686018427387904 = Overflow +17 * ~2305843009213693952 = Overflow +17 * ~1152921504606846976 = Overflow +17 * ~576460752303423488 = Overflow +18 * ~9223372036854775808 = Overflow +18 * ~4611686018427387904 = Overflow +18 * ~2305843009213693952 = Overflow +18 * ~1152921504606846976 = Overflow +18 * ~576460752303423488 = Overflow +19 * ~9223372036854775808 = Overflow +19 * ~4611686018427387904 = Overflow +19 * ~2305843009213693952 = Overflow +19 * ~1152921504606846976 = Overflow +19 * ~576460752303423488 = Overflow +20 * ~9223372036854775808 = Overflow +20 * ~4611686018427387904 = Overflow +20 * ~2305843009213693952 = Overflow +20 * ~1152921504606846976 = Overflow +20 * ~576460752303423488 = Overflow +21 * ~9223372036854775808 = Overflow +21 * ~4611686018427387904 = Overflow +21 * ~2305843009213693952 = Overflow +21 * ~1152921504606846976 = Overflow +21 * ~576460752303423488 = Overflow +22 * ~9223372036854775808 = Overflow +22 * ~4611686018427387904 = Overflow +22 * ~2305843009213693952 = Overflow +22 * ~1152921504606846976 = Overflow +22 * ~576460752303423488 = Overflow +23 * ~9223372036854775808 = Overflow +23 * ~4611686018427387904 = Overflow +23 * ~2305843009213693952 = Overflow +23 * ~1152921504606846976 = Overflow +23 * ~576460752303423488 = Overflow +24 * ~9223372036854775808 = Overflow +24 * ~4611686018427387904 = Overflow +24 * ~2305843009213693952 = Overflow +24 * ~1152921504606846976 = Overflow +24 * ~576460752303423488 = Overflow +25 * ~9223372036854775808 = Overflow +25 * ~4611686018427387904 = Overflow +25 * ~2305843009213693952 = Overflow +25 * ~1152921504606846976 = Overflow +25 * ~576460752303423488 = Overflow +26 * ~9223372036854775808 = Overflow +26 * ~4611686018427387904 = Overflow +26 * ~2305843009213693952 = Overflow +26 * ~1152921504606846976 = Overflow +26 * ~576460752303423488 = Overflow +27 * ~9223372036854775808 = Overflow +27 * ~4611686018427387904 = Overflow +27 * ~2305843009213693952 = Overflow +27 * ~1152921504606846976 = Overflow +27 * ~576460752303423488 = Overflow +28 * ~9223372036854775808 = Overflow +28 * ~4611686018427387904 = Overflow +28 * ~2305843009213693952 = Overflow +28 * ~1152921504606846976 = Overflow +28 * ~576460752303423488 = Overflow +29 * ~9223372036854775808 = Overflow +29 * ~4611686018427387904 = Overflow +29 * ~2305843009213693952 = Overflow +29 * ~1152921504606846976 = Overflow +29 * ~576460752303423488 = Overflow +30 * ~9223372036854775808 = Overflow +30 * ~4611686018427387904 = Overflow +30 * ~2305843009213693952 = Overflow +30 * ~1152921504606846976 = Overflow +30 * ~576460752303423488 = Overflow +31 * ~9223372036854775808 = Overflow +31 * ~4611686018427387904 = Overflow +31 * ~2305843009213693952 = Overflow +31 * ~1152921504606846976 = Overflow +31 * ~576460752303423488 = Overflow +32 * ~9223372036854775808 = Overflow +32 * ~4611686018427387904 = Overflow +32 * ~2305843009213693952 = Overflow +32 * ~1152921504606846976 = Overflow +32 * ~576460752303423488 = Overflow +~9223372036854775808 * 1 = ~9223372036854775808 +~9223372036854775808 * 2 = Overflow +~9223372036854775808 * 4 = Overflow +~9223372036854775808 * 8 = Overflow +~9223372036854775808 * 16 = Overflow +~4611686018427387904 * 1 = ~4611686018427387904 +~4611686018427387904 * 2 = ~9223372036854775808 +~4611686018427387904 * 4 = Overflow +~4611686018427387904 * 8 = Overflow +~4611686018427387904 * 16 = Overflow +~2305843009213693952 * 1 = ~2305843009213693952 +~2305843009213693952 * 2 = ~4611686018427387904 +~2305843009213693952 * 4 = ~9223372036854775808 +~2305843009213693952 * 8 = Overflow +~2305843009213693952 * 16 = Overflow +~1152921504606846976 * 1 = ~1152921504606846976 +~1152921504606846976 * 2 = ~2305843009213693952 +~1152921504606846976 * 4 = ~4611686018427387904 +~1152921504606846976 * 8 = ~9223372036854775808 +~1152921504606846976 * 16 = Overflow +~576460752303423488 * 1 = ~576460752303423488 +~576460752303423488 * 2 = ~1152921504606846976 +~576460752303423488 * 4 = ~2305843009213693952 +~576460752303423488 * 8 = ~4611686018427387904 +~576460752303423488 * 16 = ~9223372036854775808 +~288230376151711744 * 1 = ~288230376151711744 +~288230376151711744 * 2 = ~576460752303423488 +~288230376151711744 * 4 = ~1152921504606846976 +~288230376151711744 * 8 = ~2305843009213693952 +~288230376151711744 * 16 = ~4611686018427387904 +~4 * 1 = ~4 +~4 * 2 = ~8 +~4 * 4 = ~16 +~4 * 8 = ~32 +~4 * 16 = ~64 +~3 * 1 = ~3 +~3 * 2 = ~6 +~3 * 4 = ~12 +~3 * 8 = ~24 +~3 * 16 = ~48 +~2 * 1 = ~2 +~2 * 2 = ~4 +~2 * 4 = ~8 +~2 * 8 = ~16 +~2 * 16 = ~32 +~1 * 1 = ~1 +~1 * 2 = ~2 +~1 * 4 = ~4 +~1 * 8 = ~8 +~1 * 16 = ~16 +0 * 1 = 0 +0 * 2 = 0 +0 * 4 = 0 +0 * 8 = 0 +0 * 16 = 0 +1 * 1 = 1 +1 * 2 = 2 +1 * 4 = 4 +1 * 8 = 8 +1 * 16 = 16 +2 * 1 = 2 +2 * 2 = 4 +2 * 4 = 8 +2 * 8 = 16 +2 * 16 = 32 +3 * 1 = 3 +3 * 2 = 6 +3 * 4 = 12 +3 * 8 = 24 +3 * 16 = 48 +4 * 1 = 4 +4 * 2 = 8 +4 * 4 = 16 +4 * 8 = 32 +4 * 16 = 64 +144115188075855872 * 1 = 144115188075855872 +144115188075855872 * 2 = 288230376151711744 +144115188075855872 * 4 = 576460752303423488 +144115188075855872 * 8 = 1152921504606846976 +144115188075855872 * 16 = 2305843009213693952 +288230376151711744 * 1 = 288230376151711744 +288230376151711744 * 2 = 576460752303423488 +288230376151711744 * 4 = 1152921504606846976 +288230376151711744 * 8 = 2305843009213693952 +288230376151711744 * 16 = 4611686018427387904 +576460752303423488 * 1 = 576460752303423488 +576460752303423488 * 2 = 1152921504606846976 +576460752303423488 * 4 = 2305843009213693952 +576460752303423488 * 8 = 4611686018427387904 +576460752303423488 * 16 = Overflow +1152921504606846976 * 1 = 1152921504606846976 +1152921504606846976 * 2 = 2305843009213693952 +1152921504606846976 * 4 = 4611686018427387904 +1152921504606846976 * 8 = Overflow +1152921504606846976 * 16 = Overflow +2305843009213693952 * 1 = 2305843009213693952 +2305843009213693952 * 2 = 4611686018427387904 +2305843009213693952 * 4 = Overflow +2305843009213693952 * 8 = Overflow +2305843009213693952 * 16 = Overflow +4611686018427387904 * 1 = 4611686018427387904 +4611686018427387904 * 2 = Overflow +4611686018427387904 * 4 = Overflow +4611686018427387904 * 8 = Overflow +4611686018427387904 * 16 = Overflow +~9223372036854775808 * ~1 = Overflow +~9223372036854775808 * ~2 = Overflow +~9223372036854775808 * ~4 = Overflow +~9223372036854775808 * ~8 = Overflow +~9223372036854775808 * ~16 = Overflow +~4611686018427387904 * ~1 = 4611686018427387904 +~4611686018427387904 * ~2 = Overflow +~4611686018427387904 * ~4 = Overflow +~4611686018427387904 * ~8 = Overflow +~4611686018427387904 * ~16 = Overflow +~2305843009213693952 * ~1 = 2305843009213693952 +~2305843009213693952 * ~2 = 4611686018427387904 +~2305843009213693952 * ~4 = Overflow +~2305843009213693952 * ~8 = Overflow +~2305843009213693952 * ~16 = Overflow +~1152921504606846976 * ~1 = 1152921504606846976 +~1152921504606846976 * ~2 = 2305843009213693952 +~1152921504606846976 * ~4 = 4611686018427387904 +~1152921504606846976 * ~8 = Overflow +~1152921504606846976 * ~16 = Overflow +~576460752303423488 * ~1 = 576460752303423488 +~576460752303423488 * ~2 = 1152921504606846976 +~576460752303423488 * ~4 = 2305843009213693952 +~576460752303423488 * ~8 = 4611686018427387904 +~576460752303423488 * ~16 = Overflow +~288230376151711744 * ~1 = 288230376151711744 +~288230376151711744 * ~2 = 576460752303423488 +~288230376151711744 * ~4 = 1152921504606846976 +~288230376151711744 * ~8 = 2305843009213693952 +~288230376151711744 * ~16 = 4611686018427387904 +~4 * ~1 = 4 +~4 * ~2 = 8 +~4 * ~4 = 16 +~4 * ~8 = 32 +~4 * ~16 = 64 +~3 * ~1 = 3 +~3 * ~2 = 6 +~3 * ~4 = 12 +~3 * ~8 = 24 +~3 * ~16 = 48 +~2 * ~1 = 2 +~2 * ~2 = 4 +~2 * ~4 = 8 +~2 * ~8 = 16 +~2 * ~16 = 32 +~1 * ~1 = 1 +~1 * ~2 = 2 +~1 * ~4 = 4 +~1 * ~8 = 8 +~1 * ~16 = 16 +0 * ~1 = 0 +0 * ~2 = 0 +0 * ~4 = 0 +0 * ~8 = 0 +0 * ~16 = 0 +1 * ~1 = ~1 +1 * ~2 = ~2 +1 * ~4 = ~4 +1 * ~8 = ~8 +1 * ~16 = ~16 +2 * ~1 = ~2 +2 * ~2 = ~4 +2 * ~4 = ~8 +2 * ~8 = ~16 +2 * ~16 = ~32 +3 * ~1 = ~3 +3 * ~2 = ~6 +3 * ~4 = ~12 +3 * ~8 = ~24 +3 * ~16 = ~48 +4 * ~1 = ~4 +4 * ~2 = ~8 +4 * ~4 = ~16 +4 * ~8 = ~32 +4 * ~16 = ~64 +144115188075855872 * ~1 = ~144115188075855872 +144115188075855872 * ~2 = ~288230376151711744 +144115188075855872 * ~4 = ~576460752303423488 +144115188075855872 * ~8 = ~1152921504606846976 +144115188075855872 * ~16 = ~2305843009213693952 +288230376151711744 * ~1 = ~288230376151711744 +288230376151711744 * ~2 = ~576460752303423488 +288230376151711744 * ~4 = ~1152921504606846976 +288230376151711744 * ~8 = ~2305843009213693952 +288230376151711744 * ~16 = ~4611686018427387904 +576460752303423488 * ~1 = ~576460752303423488 +576460752303423488 * ~2 = ~1152921504606846976 +576460752303423488 * ~4 = ~2305843009213693952 +576460752303423488 * ~8 = ~4611686018427387904 +576460752303423488 * ~16 = ~9223372036854775808 +1152921504606846976 * ~1 = ~1152921504606846976 +1152921504606846976 * ~2 = ~2305843009213693952 +1152921504606846976 * ~4 = ~4611686018427387904 +1152921504606846976 * ~8 = ~9223372036854775808 +1152921504606846976 * ~16 = Overflow +2305843009213693952 * ~1 = ~2305843009213693952 +2305843009213693952 * ~2 = ~4611686018427387904 +2305843009213693952 * ~4 = ~9223372036854775808 +2305843009213693952 * ~8 = Overflow +2305843009213693952 * ~16 = Overflow +4611686018427387904 * ~1 = ~4611686018427387904 +4611686018427387904 * ~2 = ~9223372036854775808 +4611686018427387904 * ~4 = Overflow +4611686018427387904 * ~8 = Overflow +4611686018427387904 * ~16 = Overflow diff --git a/regression/int-mul-pow2.sml b/regression/int-mul-pow2.sml new file mode 100644 index 0000000000..ac3c3f9461 --- /dev/null +++ b/regression/int-mul-pow2.sml @@ -0,0 +1,187 @@ +functor Test(structure Int: + sig + include INTEGER + val zero: int + val one: int + end) = +struct + +val zero = Int.zero +val one = Int.one +val two = Int.+ (one, one) +val three = Int.+ (two, one) +val four = Int.* (two, two) +val eight = Int.* (four, two) +val sixteen = Int.* (eight, two) +val thirtytwo = Int.* (sixteen, two) + +val maxposint = valOf Int.maxInt +val maxnegpow2 = Int.- (Int.~ maxposint, one) +val maxpospow2 = Int.+ (Int.quot (maxposint, two), one) + +fun doit k = +let + val i = maxpospow2 + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.quot (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.quot (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.quot (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.quot (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) +in + () +end + +fun loop k = + if Int.> (k, thirtytwo) + then () + else (doit k; loop (Int.+ (k, one))) + +val () = loop (Int.~ thirtytwo) + +fun doit k = +let + val i = maxnegpow2 + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.quot (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.quot (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.quot (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.quot (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) +in + () +end + +fun loop k = + if Int.> (k, thirtytwo) + then () + else (doit k; loop (Int.+ (k, one))) + +val () = loop (Int.~ thirtytwo) + +val ks = [maxnegpow2, Int.quot (maxnegpow2, two), Int.quot (maxnegpow2, four), + Int.quot (maxnegpow2, eight), Int.quot (maxnegpow2, sixteen), Int.quot (maxnegpow2, thirtytwo), + Int.~ four, Int.~ three, Int.~ two, Int.~ one, + zero, + one, two, three, four, + Int.quot (maxpospow2, thirtytwo), Int.quot (maxpospow2, sixteen), Int.quot (maxpospow2, eight), + Int.quot (maxpospow2, four), Int.quot (maxpospow2, two), maxpospow2] + +fun doit k = +let + val i = one + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.* (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.* (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.* (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.* (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) +in + () +end + +fun loop ks = + case ks of + [] => () + | k::ks => (doit k; loop ks) + +val () = loop ks + +fun doit k = +let + val i = Int.~ one + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.* (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.* (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.* (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) + val i = Int.* (i, two) + val () = print (concat [Int.toString k, " * ", Int.toString i, " = ", + (Int.toString (Int.* (k, i)) + handle Overflow => "Overflow"), "\n"]) +in + () +end + +fun loop ks = + case ks of + [] => () + | k::ks => (doit k; loop ks) + +val () = loop ks + +end + +structure Test8 = Test(structure Int = + struct + open Int8 + val zero: int = 0 + val one: int = 1 + end) +structure Test16 = Test(structure Int = + struct + open Int16 + val zero: int = 0 + val one: int = 1 + end) +structure Test32 = Test(structure Int = + struct + open Int32 + val zero: int = 0 + val one: int = 1 + end) +structure Test64 = Test(structure Int = + struct + open Int64 + val zero: int = 0 + val one: int = 1 + end) diff --git a/runtime/basis-ffi.h b/runtime/basis-ffi.h index 41f4df17be..4c7e5af415 100644 --- a/runtime/basis-ffi.h +++ b/runtime/basis-ffi.h @@ -938,6 +938,7 @@ MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_andb(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t Word16_equal(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_lshift(Word16_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_neg(Word16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t Word16_negCheckP(Int16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_notb(Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_orb(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_rol(Word16_t,Word32_t); @@ -950,6 +951,7 @@ MLTON_CODEGEN_STATIC_INLINE Real32_t Word32_castToReal32(Word32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t Word32_equal(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_lshift(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_neg(Word32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t Word32_negCheckP(Int32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_notb(Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_orb(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_rol(Word32_t,Word32_t); @@ -964,6 +966,7 @@ MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_fetch(Ref(Word64_t)); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_lshift(Word64_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE void Word64_move(Ref(Word64_t),Ref(Word64_t)); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_neg(Word64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t Word64_negCheckP(Int64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_notb(Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_orb(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_rol(Word64_t,Word32_t); @@ -976,13 +979,14 @@ MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_andb(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t Word8_equal(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_lshift(Word8_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_neg(Word8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t Word8_negCheckP(Int8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_notb(Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_orb(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_rol(Word8_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_ror(Word8_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_sub(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_xorb(Word8_t,Word8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_addCheckOverflows(Int16_t,Int16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_addCheckP(Int16_t,Int16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordS16_extdToWord16(Int16_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordS16_extdToWord32(Int16_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordS16_extdToWord64(Int16_t); @@ -992,15 +996,14 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_gt(Int16_t,Int16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_le(Int16_t,Int16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_lt(Int16_t,Int16_t); MLTON_CODEGEN_STATIC_INLINE Int16_t WordS16_mul(Int16_t,Int16_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_mulCheckOverflows(Int16_t,Int16_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_negCheckOverflows(Int16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_mulCheckP(Int16_t,Int16_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int16_t WordS16_quot(Int16_t,Int16_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int16_t WordS16_rem(Int16_t,Int16_t); PRIVATE Real32_t WordS16_rndToReal32(Int16_t); PRIVATE Real64_t WordS16_rndToReal64(Int16_t); MLTON_CODEGEN_STATIC_INLINE Int16_t WordS16_rshift(Int16_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_subCheckOverflows(Int16_t,Int16_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_addCheckOverflows(Int32_t,Int32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_subCheckP(Int16_t,Int16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_addCheckP(Int32_t,Int32_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordS32_extdToWord16(Int32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordS32_extdToWord32(Int32_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordS32_extdToWord64(Int32_t); @@ -1010,15 +1013,14 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_gt(Int32_t,Int32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_le(Int32_t,Int32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_lt(Int32_t,Int32_t); MLTON_CODEGEN_STATIC_INLINE Int32_t WordS32_mul(Int32_t,Int32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_mulCheckOverflows(Int32_t,Int32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_negCheckOverflows(Int32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_mulCheckP(Int32_t,Int32_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int32_t WordS32_quot(Int32_t,Int32_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int32_t WordS32_rem(Int32_t,Int32_t); PRIVATE Real32_t WordS32_rndToReal32(Int32_t); PRIVATE Real64_t WordS32_rndToReal64(Int32_t); MLTON_CODEGEN_STATIC_INLINE Int32_t WordS32_rshift(Int32_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_subCheckOverflows(Int32_t,Int32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_addCheckOverflows(Int64_t,Int64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_subCheckP(Int32_t,Int32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_addCheckP(Int64_t,Int64_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordS64_extdToWord16(Int64_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordS64_extdToWord32(Int64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordS64_extdToWord64(Int64_t); @@ -1028,15 +1030,14 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_gt(Int64_t,Int64_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_le(Int64_t,Int64_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_lt(Int64_t,Int64_t); MLTON_CODEGEN_STATIC_INLINE Int64_t WordS64_mul(Int64_t,Int64_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_mulCheckOverflows(Int64_t,Int64_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_negCheckOverflows(Int64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_mulCheckP(Int64_t,Int64_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int64_t WordS64_quot(Int64_t,Int64_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int64_t WordS64_rem(Int64_t,Int64_t); PRIVATE Real32_t WordS64_rndToReal32(Int64_t); PRIVATE Real64_t WordS64_rndToReal64(Int64_t); MLTON_CODEGEN_STATIC_INLINE Int64_t WordS64_rshift(Int64_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_subCheckOverflows(Int64_t,Int64_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_addCheckOverflows(Int8_t,Int8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_subCheckP(Int64_t,Int64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_addCheckP(Int8_t,Int8_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordS8_extdToWord16(Int8_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordS8_extdToWord32(Int8_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordS8_extdToWord64(Int8_t); @@ -1046,15 +1047,14 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_gt(Int8_t,Int8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_le(Int8_t,Int8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_lt(Int8_t,Int8_t); MLTON_CODEGEN_STATIC_INLINE Int8_t WordS8_mul(Int8_t,Int8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_mulCheckOverflows(Int8_t,Int8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_negCheckOverflows(Int8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_mulCheckP(Int8_t,Int8_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int8_t WordS8_quot(Int8_t,Int8_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int8_t WordS8_rem(Int8_t,Int8_t); PRIVATE Real32_t WordS8_rndToReal32(Int8_t); PRIVATE Real64_t WordS8_rndToReal64(Int8_t); MLTON_CODEGEN_STATIC_INLINE Int8_t WordS8_rshift(Int8_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_subCheckOverflows(Int8_t,Int8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_addCheckOverflows(Word16_t,Word16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_subCheckP(Int8_t,Int8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_addCheckP(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_extdToWord16(Word16_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU16_extdToWord32(Word16_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU16_extdToWord64(Word16_t); @@ -1064,13 +1064,13 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_gt(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_le(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_lt(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_mul(Word16_t,Word16_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_mulCheckOverflows(Word16_t,Word16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_mulCheckP(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_quot(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_rem(Word16_t,Word16_t); PRIVATE Real32_t WordU16_rndToReal32(Word16_t); PRIVATE Real64_t WordU16_rndToReal64(Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_rshift(Word16_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_addCheckOverflows(Word32_t,Word32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_addCheckP(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU32_extdToWord16(Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_extdToWord32(Word32_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU32_extdToWord64(Word32_t); @@ -1080,13 +1080,13 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_gt(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_le(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_lt(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_mul(Word32_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_mulCheckOverflows(Word32_t,Word32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_mulCheckP(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_quot(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_rem(Word32_t,Word32_t); PRIVATE Real32_t WordU32_rndToReal32(Word32_t); PRIVATE Real64_t WordU32_rndToReal64(Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_rshift(Word32_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_addCheckOverflows(Word64_t,Word64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_addCheckP(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU64_extdToWord16(Word64_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU64_extdToWord32(Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_extdToWord64(Word64_t); @@ -1096,13 +1096,13 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_gt(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_le(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_lt(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_mul(Word64_t,Word64_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_mulCheckOverflows(Word64_t,Word64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_mulCheckP(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_quot(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_rem(Word64_t,Word64_t); PRIVATE Real32_t WordU64_rndToReal32(Word64_t); PRIVATE Real64_t WordU64_rndToReal64(Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_rshift(Word64_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_addCheckOverflows(Word8_t,Word8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_addCheckP(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU8_extdToWord16(Word8_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU8_extdToWord32(Word8_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU8_extdToWord64(Word8_t); @@ -1112,7 +1112,7 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_gt(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_le(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_lt(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t WordU8_mul(Word8_t,Word8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_mulCheckOverflows(Word8_t,Word8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_mulCheckP(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t WordU8_quot(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t WordU8_rem(Word8_t,Word8_t); PRIVATE Real32_t WordU8_rndToReal32(Word8_t); diff --git a/runtime/basis/Word/Word-check.h b/runtime/basis/Word/Word-check.h index 290cca29ec..4a5105e5d4 100644 --- a/runtime/basis/Word/Word-check.h +++ b/runtime/basis/Word/Word-check.h @@ -1,102 +1,70 @@ - -#define WordS_addCheckBody(size, x, y, doOverflow, doSuccess) \ +#define add_overflow_b(x, y, kind, onOverflow, onSuccess) \ do { \ - if (x >= 0) { \ - if (y > WordS##size##_max - x) { \ - doOverflow; \ - } \ - } else if (y < WordS##size##_min - x) { \ - doOverflow; \ + Word##kind res; \ + if (__builtin_add_overflow(x, y, &res)) { \ + onOverflow; \ } \ - doSuccess; \ + onSuccess; \ } while (0) -#define WordS_addCheckBodyCX(size, c, x, doOverflow, doSuccess) \ -WordS_addCheckBody(size, c, x, doOverflow, doSuccess) - -#define WordU_addCheckBody(size, x, y, doOverflow, doSuccess) \ +#define sub_overflow_b(x, y, kind, onOverflow, onSuccess) \ do { \ - if (y > Word##size##_max - x) { \ - doOverflow; \ + Word##kind res; \ + if (__builtin_sub_overflow(x, y, &res)) { \ + onOverflow; \ } \ - doSuccess; \ + onSuccess; \ } while (0) -#define WordU_addCheckBodyCX(size, c, x, doOverflow, doSuccess) \ -WordU_addCheckBody(size, c, x, doOverflow, doSuccess) - -#define WordS_mulCheckBody(size, x, y, doOverflow, doSuccess) \ +#define mul_overflow_b(x, y, kind, onOverflow, onSuccess) \ do { \ - if ((x == (WordS##size)0) || (y == (WordS##size)0)) { \ - } else \ - if (x > (WordS## size)0) { \ - if (y > (WordS##size)0) { \ - if (x > WordS##size##_quot (WordS##size##_max, y)) { \ - doOverflow; \ - } \ - } else /* (y < (WordS##size)0) */ { \ - if (y < WordS##size##_quot (WordS##size##_min, x)) { \ - doOverflow; \ - } \ - } \ - } else /* (x < (WordS##size)0) */ { \ - if (y > (WordS##size)0) { \ - if (x < WordS##size##_quot (WordS##size##_min, y)) { \ - doOverflow; \ - } \ - } else /* (y < (WordS##size)0) */ { \ - if (y < WordS##size##_quot (WordS##size##_max, x)) { \ - doOverflow; \ - } \ - } \ + Word##kind res; \ + if (__builtin_mul_overflow(x, y, &res)) { \ + onOverflow; \ } \ - doSuccess; \ + onSuccess; \ } while (0) -// #undef WordS_mulCheckBody -#define WordU_mulCheckBody(size, x, y, doOverflow, doSuccess) \ +#define neg_overflow_b(x, kind, onOverflow, onSuccess) \ do { \ - if ((x == (WordU##size)0) || (y == (WordU##size)0)) { \ - } else \ - if (x > WordU##size##_quot (Word##size##_max, y)) { \ - doOverflow; \ + Word##kind res; \ + if (__builtin_sub_overflow(0, x, &res)) { \ + onOverflow; \ } \ - doSuccess; \ + onSuccess; \ } while (0) -// #undef WordU_mulCheckBody -/* #define Word_mulCheckBody(small, large, x, y, doOverflow, doSuccess) \ */ -/* do { \ */ -/* Word##large tmp; \ */ -/* Word##small res; \ */ -/* tmp = ((Word##large)x) * ((Word##large)y); \ */ -/* res = (Word##small)tmp; \ */ -/* if (tmp != res) { \ */ -/* doOverflow; \ */ -/* } \ */ -/* doSuccess; \ */ -/* } while (0) */ -/* #define WordS_mulCheckBody(small, large, x, y, doOverflow, doSuccess) \ */ -/* Word_mulCheckBody(S##small, S##large, x, y, doOverflow, doSuccess) */ -/* #define WordU_mulCheckBody(small, large, x, y, doOverflow, doSuccess) \ */ -/* Word_mulCheckBody(U##small, U##large, x, y, doOverflow, doSuccess) */ + +/** + * Old-style overflow operators + */ + +#define WordS_addCheckBody(size, x, y, doOverflow, doSuccess) \ + add_overflow_b(x, y, S##size, doOverflow, doSuccess) +#define WordS_addCheckBodyCX(size, c, x, doOverflow, doSuccess) \ + WordS_addCheckBody(size, c, x, doOverflow, doSuccess) + +#define WordU_addCheckBody(size, x, y, doOverflow, doSuccess) \ + add_overflow_b(x, y, U##size, doOverflow, doSuccess) +#define WordU_addCheckBodyCX(size, c, x, doOverflow, doSuccess) \ + WordU_addCheckBody(size, c, x, doOverflow, doSuccess) + +#define WordS_mulCheckBody(size, x, y, doOverflow, doSuccess) \ + mul_overflow_b(x, y, S##size, doOverflow, doSuccess) + +#define WordU_mulCheckBody(size, x, y, doOverflow, doSuccess) \ + mul_overflow_b(x, y, U##size, doOverflow, doSuccess) #define WordS_negCheckBody(size, x, doOverflow, doSuccess) \ - do { \ - if (x == WordS##size##_min) { \ - doOverflow; \ - } \ - doSuccess; \ - } while (0) + neg_overflow_b(x, S##size, doOverflow, doSuccess) +#define WordS_subCheckBody(size, x, y, doOverflow, doSuccess) \ + sub_overflow_b(x, y, S##size, doOverflow, doSuccess) #define WordS_subCheckBodyCX(size, c, x, doOverflow, doSuccess) \ - do { \ - if (c >= 0) { \ - if (x < c - WordS##size##_max) { \ - doOverflow; \ - } \ - } else if (x > c - WordS##size##_min) { \ - doOverflow; \ - } \ - doSuccess; \ - } while (0) + WordS_subCheckBody(size, c, x, doOverflow, doSuccess) + #define WordS_subCheckBodyXC(size, x, c, doOverflow, doSuccess) \ + WordS_subCheckBody(size, x, c, doOverflow, doSuccess) + +/* + * Old WordS_subCheckBodyXC: + * do { \ if (c <= 0) { \ if (x > WordS##size##_max + c) { \ @@ -107,52 +75,54 @@ WordU_addCheckBody(size, c, x, doOverflow, doSuccess) } \ doSuccess; \ } while (0) -#define WordS_subCheckBody(size, x, y, doOverflow, doSuccess) \ -WordS_subCheckBodyCX(size, x, y, doOverflow, doSuccess) + */ +/** + * New-style overflow operators + */ -#define WordS_addCheckOverflows(size) \ +#define WordS_addCheckP(size) \ MLTON_CODEGEN_STATIC_INLINE \ - Bool WordS##size##_addCheckOverflows (WordS##size x, WordS##size y) { \ - WordS_addCheckBody(size, x, y, return TRUE, return FALSE); \ + Bool WordS##size##_addCheckP (WordS##size x, WordS##size y) { \ + add_overflow_b(x, y, S##size, return TRUE, return FALSE); \ } -#define WordU_addCheckOverflows(size) \ +#define WordU_addCheckP(size) \ MLTON_CODEGEN_STATIC_INLINE \ - Bool WordU##size##_addCheckOverflows (WordU##size x, WordU##size y) { \ - WordU_addCheckBody(size, x, y, return TRUE, return FALSE); \ + Bool WordU##size##_addCheckP (WordU##size x, WordU##size y) { \ + add_overflow_b(x, y, U##size, return TRUE, return FALSE); \ } -#define WordS_mulCheckOverflows(size) \ +#define WordS_mulCheckP(size) \ MLTON_CODEGEN_STATIC_INLINE \ - Bool WordS##size##_mulCheckOverflows (WordS##size x, WordS##size y) { \ - WordS_mulCheckBody(size, x, y, return TRUE, return FALSE); \ + Bool WordS##size##_mulCheckP (WordS##size x, WordS##size y) { \ + mul_overflow_b(x, y, S##size, return TRUE, return FALSE); \ } -#define WordU_mulCheckOverflows(size) \ +#define WordU_mulCheckP(size) \ MLTON_CODEGEN_STATIC_INLINE \ - Bool WordU##size##_mulCheckOverflows (WordU##size x, WordU##size y) { \ - WordU_mulCheckBody(size, x, y, return TRUE, return FALSE); \ + Bool WordU##size##_mulCheckP (WordU##size x, WordU##size y) { \ + mul_overflow_b(x, y, U##size, return TRUE, return FALSE); \ } -#define WordS_negCheckOverflows(size) \ +#define Word_negCheckP(size) \ MLTON_CODEGEN_STATIC_INLINE \ - Bool WordS##size##_negCheckOverflows (WordS##size x) { \ - WordS_negCheckBody(size, x, return TRUE, return FALSE); \ + Bool Word##size##_negCheckP (WordS##size x) { \ + neg_overflow_b(x, S##size, return TRUE, return FALSE); \ } -#define WordS_subCheckOverflows(size) \ +#define WordS_subCheckP(size) \ MLTON_CODEGEN_STATIC_INLINE \ - Bool WordS##size##_subCheckOverflows (WordS##size x, WordS##size y) { \ - WordS_subCheckBody(size, x, y, return TRUE, return FALSE); \ + Bool WordS##size##_subCheckP (WordS##size x, WordS##size y) { \ + sub_overflow_b(x, y, S##size, return TRUE, return FALSE); \ } #define all(size) \ -WordS_addCheckOverflows(size) \ -WordU_addCheckOverflows(size) \ -WordS_mulCheckOverflows(size) \ -WordU_mulCheckOverflows(size) \ -WordS_negCheckOverflows(size) \ -WordS_subCheckOverflows(size) +WordS_addCheckP(size) \ +WordU_addCheckP(size) \ +WordS_mulCheckP(size) \ +WordU_mulCheckP(size) \ +Word_negCheckP(size) \ +WordS_subCheckP(size) all(8) all(16) @@ -160,9 +130,9 @@ all(32) all(64) #undef all -#undef WordS_subCheckOverflows -#undef WordS_negCheckOverflows -#undef WordU_mulCheckOverflows -#undef WordS_mulCheckOverflows -#undef WordU_addCheckOverflows -#undef WordS_addCheckOverflows +#undef WordS_subCheckP +#undef Word_negCheckP +#undef WordU_mulCheckP +#undef WordS_mulCheckP +#undef WordU_addCheckP +#undef WordS_addCheckP diff --git a/runtime/basis/Word/Word-ops.h b/runtime/basis/Word/Word-ops.h index 7ab3bd1198..1b85201b13 100644 --- a/runtime/basis/Word/Word-ops.h +++ b/runtime/basis/Word/Word-ops.h @@ -5,10 +5,22 @@ return w1 op w2; \ } +#define binaryBuiltin(kind, name, builtin) \ + MLTON_CODEGEN_STATIC_INLINE \ + Word##kind Word##kind##_##name (Word##kind w1, Word##kind w2) { \ + Word##kind res; \ + __builtin_##builtin##_overflow(w1, w2, &res); \ + return res; \ + } + #define bothBinary(size, name, op) \ binary (S##size, name, op) \ binary (U##size, name, op) +#define bothBinaryBuiltin(size, name, builtin) \ + binaryBuiltin(S##size, name, builtin) \ + binaryBuiltin(U##size, name, builtin) + #define compare(kind, name, op) \ MLTON_CODEGEN_STATIC_INLINE \ Bool Word##kind##_##name (Word##kind w1, Word##kind w2) { \ @@ -62,7 +74,7 @@ compare (U##size, name, op) } #define all(size) \ -binary (size, add, +) \ +binaryBuiltin (size, add, add) \ binary (size, andb, &) \ compare (size, equal, ==) \ bothCompare (size, ge, >=) \ @@ -70,7 +82,7 @@ bothCompare (size, gt, >) \ bothCompare (size, le, <=) \ shift (size, lshift, <<) \ bothCompare (size, lt, <) \ -bothBinary (size, mul, *) \ +bothBinaryBuiltin (size, mul, mul) \ unary (size, neg, -) \ unary (size, notb, ~) \ /* WordS_quot and WordS_rem can't be inlined with the C-codegen, \ @@ -89,7 +101,7 @@ ror(size) \ */ \ shift (S##size, rshift, >>) \ shift (U##size, rshift, >>) \ -binary (size, sub, -) \ +binaryBuiltin (size, sub, sub) \ binary (size, xorb, ^) all (8) diff --git a/runtime/gen/basis-ffi.def b/runtime/gen/basis-ffi.def index 8a38c5c71a..db591459f5 100644 --- a/runtime/gen/basis-ffi.def +++ b/runtime/gen/basis-ffi.def @@ -979,7 +979,7 @@ Word8.rol = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word32.t -> Word8.t Word8.ror = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word32.t -> Word8.t Word8.sub = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Word8.t Word8.xorb = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Word8.t -WordS16.addCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Bool.t +WordS16.addCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Bool.t WordS16.extdToWord16 = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t -> Word16.t WordS16.extdToWord32 = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t -> Word32.t WordS16.extdToWord64 = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t -> Word64.t @@ -989,15 +989,15 @@ WordS16.gt = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Bool.t WordS16.le = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Bool.t WordS16.lt = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Bool.t WordS16.mul = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Int16.t -WordS16.mulCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Bool.t -WordS16.negCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t -> Bool.t +WordS16.mulCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Bool.t +Word16.negCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t -> Bool.t WordS16.quot = _import MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) : Int16.t * Int16.t -> Int16.t WordS16.rem = _import MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) : Int16.t * Int16.t -> Int16.t WordS16.rndToReal32 = _import PRIVATE : Int16.t -> Real32.t WordS16.rndToReal64 = _import PRIVATE : Int16.t -> Real64.t WordS16.rshift = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Word32.t -> Int16.t -WordS16.subCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Bool.t -WordS32.addCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Bool.t +WordS16.subCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int16.t * Int16.t -> Bool.t +WordS32.addCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Bool.t WordS32.extdToWord16 = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t -> Word16.t WordS32.extdToWord32 = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t -> Word32.t WordS32.extdToWord64 = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t -> Word64.t @@ -1007,15 +1007,15 @@ WordS32.gt = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Bool.t WordS32.le = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Bool.t WordS32.lt = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Bool.t WordS32.mul = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Int32.t -WordS32.mulCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Bool.t -WordS32.negCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t -> Bool.t +WordS32.mulCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Bool.t +Word32.negCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t -> Bool.t WordS32.quot = _import MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) : Int32.t * Int32.t -> Int32.t WordS32.rem = _import MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) : Int32.t * Int32.t -> Int32.t WordS32.rndToReal32 = _import PRIVATE : Int32.t -> Real32.t WordS32.rndToReal64 = _import PRIVATE : Int32.t -> Real64.t WordS32.rshift = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Word32.t -> Int32.t -WordS32.subCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Bool.t -WordS64.addCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Bool.t +WordS32.subCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int32.t * Int32.t -> Bool.t +WordS64.addCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Bool.t WordS64.extdToWord16 = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t -> Word16.t WordS64.extdToWord32 = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t -> Word32.t WordS64.extdToWord64 = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t -> Word64.t @@ -1025,15 +1025,15 @@ WordS64.gt = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Bool.t WordS64.le = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Bool.t WordS64.lt = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Bool.t WordS64.mul = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Int64.t -WordS64.mulCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Bool.t -WordS64.negCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t -> Bool.t +WordS64.mulCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Bool.t +Word64.negCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t -> Bool.t WordS64.quot = _import MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) : Int64.t * Int64.t -> Int64.t WordS64.rem = _import MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) : Int64.t * Int64.t -> Int64.t WordS64.rndToReal32 = _import PRIVATE : Int64.t -> Real32.t WordS64.rndToReal64 = _import PRIVATE : Int64.t -> Real64.t WordS64.rshift = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Word32.t -> Int64.t -WordS64.subCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Bool.t -WordS8.addCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Bool.t +WordS64.subCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int64.t * Int64.t -> Bool.t +WordS8.addCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Bool.t WordS8.extdToWord16 = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t -> Word16.t WordS8.extdToWord32 = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t -> Word32.t WordS8.extdToWord64 = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t -> Word64.t @@ -1043,15 +1043,15 @@ WordS8.gt = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Bool.t WordS8.le = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Bool.t WordS8.lt = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Bool.t WordS8.mul = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Int8.t -WordS8.mulCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Bool.t -WordS8.negCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t -> Bool.t +WordS8.mulCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Bool.t +Word8.negCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t -> Bool.t WordS8.quot = _import MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) : Int8.t * Int8.t -> Int8.t WordS8.rem = _import MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) : Int8.t * Int8.t -> Int8.t WordS8.rndToReal32 = _import PRIVATE : Int8.t -> Real32.t WordS8.rndToReal64 = _import PRIVATE : Int8.t -> Real64.t WordS8.rshift = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Word32.t -> Int8.t -WordS8.subCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Bool.t -WordU16.addCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Bool.t +WordS8.subCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Int8.t * Int8.t -> Bool.t +WordU16.addCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Bool.t WordU16.extdToWord16 = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t -> Word16.t WordU16.extdToWord32 = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t -> Word32.t WordU16.extdToWord64 = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t -> Word64.t @@ -1061,13 +1061,13 @@ WordU16.gt = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Bool.t WordU16.le = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Bool.t WordU16.lt = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Bool.t WordU16.mul = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Word16.t -WordU16.mulCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Bool.t +WordU16.mulCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Bool.t WordU16.quot = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Word16.t WordU16.rem = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word16.t -> Word16.t WordU16.rndToReal32 = _import PRIVATE : Word16.t -> Real32.t WordU16.rndToReal64 = _import PRIVATE : Word16.t -> Real64.t WordU16.rshift = _import MLTON_CODEGEN_STATIC_INLINE : Word16.t * Word32.t -> Word16.t -WordU32.addCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Bool.t +WordU32.addCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Bool.t WordU32.extdToWord16 = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t -> Word16.t WordU32.extdToWord32 = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t -> Word32.t WordU32.extdToWord64 = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t -> Word64.t @@ -1077,13 +1077,13 @@ WordU32.gt = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Bool.t WordU32.le = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Bool.t WordU32.lt = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Bool.t WordU32.mul = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Word32.t -WordU32.mulCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Bool.t +WordU32.mulCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Bool.t WordU32.quot = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Word32.t WordU32.rem = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Word32.t WordU32.rndToReal32 = _import PRIVATE : Word32.t -> Real32.t WordU32.rndToReal64 = _import PRIVATE : Word32.t -> Real64.t WordU32.rshift = _import MLTON_CODEGEN_STATIC_INLINE : Word32.t * Word32.t -> Word32.t -WordU64.addCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Bool.t +WordU64.addCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Bool.t WordU64.extdToWord16 = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t -> Word16.t WordU64.extdToWord32 = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t -> Word32.t WordU64.extdToWord64 = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t -> Word64.t @@ -1093,13 +1093,13 @@ WordU64.gt = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Bool.t WordU64.le = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Bool.t WordU64.lt = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Bool.t WordU64.mul = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Word64.t -WordU64.mulCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Bool.t +WordU64.mulCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Bool.t WordU64.quot = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Word64.t WordU64.rem = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word64.t -> Word64.t WordU64.rndToReal32 = _import PRIVATE : Word64.t -> Real32.t WordU64.rndToReal64 = _import PRIVATE : Word64.t -> Real64.t WordU64.rshift = _import MLTON_CODEGEN_STATIC_INLINE : Word64.t * Word32.t -> Word64.t -WordU8.addCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Bool.t +WordU8.addCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Bool.t WordU8.extdToWord16 = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t -> Word16.t WordU8.extdToWord32 = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t -> Word32.t WordU8.extdToWord64 = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t -> Word64.t @@ -1109,7 +1109,7 @@ WordU8.gt = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Bool.t WordU8.le = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Bool.t WordU8.lt = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Bool.t WordU8.mul = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Word8.t -WordU8.mulCheckOverflows = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Bool.t +WordU8.mulCheckP = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Bool.t WordU8.quot = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Word8.t WordU8.rem = _import MLTON_CODEGEN_STATIC_INLINE : Word8.t * Word8.t -> Word8.t WordU8.rndToReal32 = _import PRIVATE : Word8.t -> Real32.t diff --git a/runtime/gen/basis-ffi.h b/runtime/gen/basis-ffi.h index 41f4df17be..4c7e5af415 100644 --- a/runtime/gen/basis-ffi.h +++ b/runtime/gen/basis-ffi.h @@ -938,6 +938,7 @@ MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_andb(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t Word16_equal(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_lshift(Word16_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_neg(Word16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t Word16_negCheckP(Int16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_notb(Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_orb(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t Word16_rol(Word16_t,Word32_t); @@ -950,6 +951,7 @@ MLTON_CODEGEN_STATIC_INLINE Real32_t Word32_castToReal32(Word32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t Word32_equal(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_lshift(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_neg(Word32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t Word32_negCheckP(Int32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_notb(Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_orb(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t Word32_rol(Word32_t,Word32_t); @@ -964,6 +966,7 @@ MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_fetch(Ref(Word64_t)); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_lshift(Word64_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE void Word64_move(Ref(Word64_t),Ref(Word64_t)); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_neg(Word64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t Word64_negCheckP(Int64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_notb(Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_orb(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t Word64_rol(Word64_t,Word32_t); @@ -976,13 +979,14 @@ MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_andb(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t Word8_equal(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_lshift(Word8_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_neg(Word8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t Word8_negCheckP(Int8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_notb(Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_orb(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_rol(Word8_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_ror(Word8_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_sub(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t Word8_xorb(Word8_t,Word8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_addCheckOverflows(Int16_t,Int16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_addCheckP(Int16_t,Int16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordS16_extdToWord16(Int16_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordS16_extdToWord32(Int16_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordS16_extdToWord64(Int16_t); @@ -992,15 +996,14 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_gt(Int16_t,Int16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_le(Int16_t,Int16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_lt(Int16_t,Int16_t); MLTON_CODEGEN_STATIC_INLINE Int16_t WordS16_mul(Int16_t,Int16_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_mulCheckOverflows(Int16_t,Int16_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_negCheckOverflows(Int16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_mulCheckP(Int16_t,Int16_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int16_t WordS16_quot(Int16_t,Int16_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int16_t WordS16_rem(Int16_t,Int16_t); PRIVATE Real32_t WordS16_rndToReal32(Int16_t); PRIVATE Real64_t WordS16_rndToReal64(Int16_t); MLTON_CODEGEN_STATIC_INLINE Int16_t WordS16_rshift(Int16_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_subCheckOverflows(Int16_t,Int16_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_addCheckOverflows(Int32_t,Int32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS16_subCheckP(Int16_t,Int16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_addCheckP(Int32_t,Int32_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordS32_extdToWord16(Int32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordS32_extdToWord32(Int32_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordS32_extdToWord64(Int32_t); @@ -1010,15 +1013,14 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_gt(Int32_t,Int32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_le(Int32_t,Int32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_lt(Int32_t,Int32_t); MLTON_CODEGEN_STATIC_INLINE Int32_t WordS32_mul(Int32_t,Int32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_mulCheckOverflows(Int32_t,Int32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_negCheckOverflows(Int32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_mulCheckP(Int32_t,Int32_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int32_t WordS32_quot(Int32_t,Int32_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int32_t WordS32_rem(Int32_t,Int32_t); PRIVATE Real32_t WordS32_rndToReal32(Int32_t); PRIVATE Real64_t WordS32_rndToReal64(Int32_t); MLTON_CODEGEN_STATIC_INLINE Int32_t WordS32_rshift(Int32_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_subCheckOverflows(Int32_t,Int32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_addCheckOverflows(Int64_t,Int64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS32_subCheckP(Int32_t,Int32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_addCheckP(Int64_t,Int64_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordS64_extdToWord16(Int64_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordS64_extdToWord32(Int64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordS64_extdToWord64(Int64_t); @@ -1028,15 +1030,14 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_gt(Int64_t,Int64_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_le(Int64_t,Int64_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_lt(Int64_t,Int64_t); MLTON_CODEGEN_STATIC_INLINE Int64_t WordS64_mul(Int64_t,Int64_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_mulCheckOverflows(Int64_t,Int64_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_negCheckOverflows(Int64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_mulCheckP(Int64_t,Int64_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int64_t WordS64_quot(Int64_t,Int64_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int64_t WordS64_rem(Int64_t,Int64_t); PRIVATE Real32_t WordS64_rndToReal32(Int64_t); PRIVATE Real64_t WordS64_rndToReal64(Int64_t); MLTON_CODEGEN_STATIC_INLINE Int64_t WordS64_rshift(Int64_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_subCheckOverflows(Int64_t,Int64_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_addCheckOverflows(Int8_t,Int8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS64_subCheckP(Int64_t,Int64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_addCheckP(Int8_t,Int8_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordS8_extdToWord16(Int8_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordS8_extdToWord32(Int8_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordS8_extdToWord64(Int8_t); @@ -1046,15 +1047,14 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_gt(Int8_t,Int8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_le(Int8_t,Int8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_lt(Int8_t,Int8_t); MLTON_CODEGEN_STATIC_INLINE Int8_t WordS8_mul(Int8_t,Int8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_mulCheckOverflows(Int8_t,Int8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_negCheckOverflows(Int8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_mulCheckP(Int8_t,Int8_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int8_t WordS8_quot(Int8_t,Int8_t); MLTON_CODEGEN_WORDSQUOTREM(MLTON_CODEGEN_STATIC_INLINE) Int8_t WordS8_rem(Int8_t,Int8_t); PRIVATE Real32_t WordS8_rndToReal32(Int8_t); PRIVATE Real64_t WordS8_rndToReal64(Int8_t); MLTON_CODEGEN_STATIC_INLINE Int8_t WordS8_rshift(Int8_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_subCheckOverflows(Int8_t,Int8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_addCheckOverflows(Word16_t,Word16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordS8_subCheckP(Int8_t,Int8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_addCheckP(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_extdToWord16(Word16_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU16_extdToWord32(Word16_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU16_extdToWord64(Word16_t); @@ -1064,13 +1064,13 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_gt(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_le(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_lt(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_mul(Word16_t,Word16_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_mulCheckOverflows(Word16_t,Word16_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU16_mulCheckP(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_quot(Word16_t,Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_rem(Word16_t,Word16_t); PRIVATE Real32_t WordU16_rndToReal32(Word16_t); PRIVATE Real64_t WordU16_rndToReal64(Word16_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU16_rshift(Word16_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_addCheckOverflows(Word32_t,Word32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_addCheckP(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU32_extdToWord16(Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_extdToWord32(Word32_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU32_extdToWord64(Word32_t); @@ -1080,13 +1080,13 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_gt(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_le(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_lt(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_mul(Word32_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_mulCheckOverflows(Word32_t,Word32_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU32_mulCheckP(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_quot(Word32_t,Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_rem(Word32_t,Word32_t); PRIVATE Real32_t WordU32_rndToReal32(Word32_t); PRIVATE Real64_t WordU32_rndToReal64(Word32_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU32_rshift(Word32_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_addCheckOverflows(Word64_t,Word64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_addCheckP(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU64_extdToWord16(Word64_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU64_extdToWord32(Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_extdToWord64(Word64_t); @@ -1096,13 +1096,13 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_gt(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_le(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_lt(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_mul(Word64_t,Word64_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_mulCheckOverflows(Word64_t,Word64_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU64_mulCheckP(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_quot(Word64_t,Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_rem(Word64_t,Word64_t); PRIVATE Real32_t WordU64_rndToReal32(Word64_t); PRIVATE Real64_t WordU64_rndToReal64(Word64_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU64_rshift(Word64_t,Word32_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_addCheckOverflows(Word8_t,Word8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_addCheckP(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word16_t WordU8_extdToWord16(Word8_t); MLTON_CODEGEN_STATIC_INLINE Word32_t WordU8_extdToWord32(Word8_t); MLTON_CODEGEN_STATIC_INLINE Word64_t WordU8_extdToWord64(Word8_t); @@ -1112,7 +1112,7 @@ MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_gt(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_le(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_lt(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t WordU8_mul(Word8_t,Word8_t); -MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_mulCheckOverflows(Word8_t,Word8_t); +MLTON_CODEGEN_STATIC_INLINE Bool_t WordU8_mulCheckP(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t WordU8_quot(Word8_t,Word8_t); MLTON_CODEGEN_STATIC_INLINE Word8_t WordU8_rem(Word8_t,Word8_t); PRIVATE Real32_t WordU8_rndToReal32(Word8_t); diff --git a/runtime/gen/basis-ffi.sml b/runtime/gen/basis-ffi.sml index 53a3b4413a..47e017bfe0 100644 --- a/runtime/gen/basis-ffi.sml +++ b/runtime/gen/basis-ffi.sml @@ -1148,6 +1148,7 @@ val andb = _import "Word16_andb" private : Word16.t * Word16.t -> Word16.t; val equal = _import "Word16_equal" private : Word16.t * Word16.t -> Bool.t; val lshift = _import "Word16_lshift" private : Word16.t * Word32.t -> Word16.t; val neg = _import "Word16_neg" private : Word16.t -> Word16.t; +val negCheckP = _import "Word16_negCheckP" private : Int16.t -> Bool.t; val notb = _import "Word16_notb" private : Word16.t -> Word16.t; val orb = _import "Word16_orb" private : Word16.t * Word16.t -> Word16.t; val rol = _import "Word16_rol" private : Word16.t * Word32.t -> Word16.t; @@ -1164,6 +1165,7 @@ val castToReal32 = _import "Word32_castToReal32" private : Word32.t -> Real32.t; val equal = _import "Word32_equal" private : Word32.t * Word32.t -> Bool.t; val lshift = _import "Word32_lshift" private : Word32.t * Word32.t -> Word32.t; val neg = _import "Word32_neg" private : Word32.t -> Word32.t; +val negCheckP = _import "Word32_negCheckP" private : Int32.t -> Bool.t; val notb = _import "Word32_notb" private : Word32.t -> Word32.t; val orb = _import "Word32_orb" private : Word32.t * Word32.t -> Word32.t; val rol = _import "Word32_rol" private : Word32.t * Word32.t -> Word32.t; @@ -1182,6 +1184,7 @@ val fetch = _import "Word64_fetch" private : (Word64.t) ref -> Word64.t; val lshift = _import "Word64_lshift" private : Word64.t * Word32.t -> Word64.t; val move = _import "Word64_move" private : (Word64.t) ref * (Word64.t) ref -> unit; val neg = _import "Word64_neg" private : Word64.t -> Word64.t; +val negCheckP = _import "Word64_negCheckP" private : Int64.t -> Bool.t; val notb = _import "Word64_notb" private : Word64.t -> Word64.t; val orb = _import "Word64_orb" private : Word64.t * Word64.t -> Word64.t; val rol = _import "Word64_rol" private : Word64.t * Word32.t -> Word64.t; @@ -1198,6 +1201,7 @@ val andb = _import "Word8_andb" private : Word8.t * Word8.t -> Word8.t; val equal = _import "Word8_equal" private : Word8.t * Word8.t -> Bool.t; val lshift = _import "Word8_lshift" private : Word8.t * Word32.t -> Word8.t; val neg = _import "Word8_neg" private : Word8.t -> Word8.t; +val negCheckP = _import "Word8_negCheckP" private : Int8.t -> Bool.t; val notb = _import "Word8_notb" private : Word8.t -> Word8.t; val orb = _import "Word8_orb" private : Word8.t * Word8.t -> Word8.t; val rol = _import "Word8_rol" private : Word8.t * Word32.t -> Word8.t; @@ -1207,7 +1211,7 @@ val xorb = _import "Word8_xorb" private : Word8.t * Word8.t -> Word8.t; end structure WordS16 = struct -val addCheckOverflows = _import "WordS16_addCheckOverflows" private : Int16.t * Int16.t -> Bool.t; +val addCheckP = _import "WordS16_addCheckP" private : Int16.t * Int16.t -> Bool.t; val extdToWord16 = _import "WordS16_extdToWord16" private : Int16.t -> Word16.t; val extdToWord32 = _import "WordS16_extdToWord32" private : Int16.t -> Word32.t; val extdToWord64 = _import "WordS16_extdToWord64" private : Int16.t -> Word64.t; @@ -1217,18 +1221,17 @@ val gt = _import "WordS16_gt" private : Int16.t * Int16.t -> Bool.t; val le = _import "WordS16_le" private : Int16.t * Int16.t -> Bool.t; val lt = _import "WordS16_lt" private : Int16.t * Int16.t -> Bool.t; val mul = _import "WordS16_mul" private : Int16.t * Int16.t -> Int16.t; -val mulCheckOverflows = _import "WordS16_mulCheckOverflows" private : Int16.t * Int16.t -> Bool.t; -val negCheckOverflows = _import "WordS16_negCheckOverflows" private : Int16.t -> Bool.t; +val mulCheckP = _import "WordS16_mulCheckP" private : Int16.t * Int16.t -> Bool.t; val quot = _import "WordS16_quot" private : Int16.t * Int16.t -> Int16.t; val rem = _import "WordS16_rem" private : Int16.t * Int16.t -> Int16.t; val rndToReal32 = _import "WordS16_rndToReal32" private : Int16.t -> Real32.t; val rndToReal64 = _import "WordS16_rndToReal64" private : Int16.t -> Real64.t; val rshift = _import "WordS16_rshift" private : Int16.t * Word32.t -> Int16.t; -val subCheckOverflows = _import "WordS16_subCheckOverflows" private : Int16.t * Int16.t -> Bool.t; +val subCheckP = _import "WordS16_subCheckP" private : Int16.t * Int16.t -> Bool.t; end structure WordS32 = struct -val addCheckOverflows = _import "WordS32_addCheckOverflows" private : Int32.t * Int32.t -> Bool.t; +val addCheckP = _import "WordS32_addCheckP" private : Int32.t * Int32.t -> Bool.t; val extdToWord16 = _import "WordS32_extdToWord16" private : Int32.t -> Word16.t; val extdToWord32 = _import "WordS32_extdToWord32" private : Int32.t -> Word32.t; val extdToWord64 = _import "WordS32_extdToWord64" private : Int32.t -> Word64.t; @@ -1238,18 +1241,17 @@ val gt = _import "WordS32_gt" private : Int32.t * Int32.t -> Bool.t; val le = _import "WordS32_le" private : Int32.t * Int32.t -> Bool.t; val lt = _import "WordS32_lt" private : Int32.t * Int32.t -> Bool.t; val mul = _import "WordS32_mul" private : Int32.t * Int32.t -> Int32.t; -val mulCheckOverflows = _import "WordS32_mulCheckOverflows" private : Int32.t * Int32.t -> Bool.t; -val negCheckOverflows = _import "WordS32_negCheckOverflows" private : Int32.t -> Bool.t; +val mulCheckP = _import "WordS32_mulCheckP" private : Int32.t * Int32.t -> Bool.t; val quot = _import "WordS32_quot" private : Int32.t * Int32.t -> Int32.t; val rem = _import "WordS32_rem" private : Int32.t * Int32.t -> Int32.t; val rndToReal32 = _import "WordS32_rndToReal32" private : Int32.t -> Real32.t; val rndToReal64 = _import "WordS32_rndToReal64" private : Int32.t -> Real64.t; val rshift = _import "WordS32_rshift" private : Int32.t * Word32.t -> Int32.t; -val subCheckOverflows = _import "WordS32_subCheckOverflows" private : Int32.t * Int32.t -> Bool.t; +val subCheckP = _import "WordS32_subCheckP" private : Int32.t * Int32.t -> Bool.t; end structure WordS64 = struct -val addCheckOverflows = _import "WordS64_addCheckOverflows" private : Int64.t * Int64.t -> Bool.t; +val addCheckP = _import "WordS64_addCheckP" private : Int64.t * Int64.t -> Bool.t; val extdToWord16 = _import "WordS64_extdToWord16" private : Int64.t -> Word16.t; val extdToWord32 = _import "WordS64_extdToWord32" private : Int64.t -> Word32.t; val extdToWord64 = _import "WordS64_extdToWord64" private : Int64.t -> Word64.t; @@ -1259,18 +1261,17 @@ val gt = _import "WordS64_gt" private : Int64.t * Int64.t -> Bool.t; val le = _import "WordS64_le" private : Int64.t * Int64.t -> Bool.t; val lt = _import "WordS64_lt" private : Int64.t * Int64.t -> Bool.t; val mul = _import "WordS64_mul" private : Int64.t * Int64.t -> Int64.t; -val mulCheckOverflows = _import "WordS64_mulCheckOverflows" private : Int64.t * Int64.t -> Bool.t; -val negCheckOverflows = _import "WordS64_negCheckOverflows" private : Int64.t -> Bool.t; +val mulCheckP = _import "WordS64_mulCheckP" private : Int64.t * Int64.t -> Bool.t; val quot = _import "WordS64_quot" private : Int64.t * Int64.t -> Int64.t; val rem = _import "WordS64_rem" private : Int64.t * Int64.t -> Int64.t; val rndToReal32 = _import "WordS64_rndToReal32" private : Int64.t -> Real32.t; val rndToReal64 = _import "WordS64_rndToReal64" private : Int64.t -> Real64.t; val rshift = _import "WordS64_rshift" private : Int64.t * Word32.t -> Int64.t; -val subCheckOverflows = _import "WordS64_subCheckOverflows" private : Int64.t * Int64.t -> Bool.t; +val subCheckP = _import "WordS64_subCheckP" private : Int64.t * Int64.t -> Bool.t; end structure WordS8 = struct -val addCheckOverflows = _import "WordS8_addCheckOverflows" private : Int8.t * Int8.t -> Bool.t; +val addCheckP = _import "WordS8_addCheckP" private : Int8.t * Int8.t -> Bool.t; val extdToWord16 = _import "WordS8_extdToWord16" private : Int8.t -> Word16.t; val extdToWord32 = _import "WordS8_extdToWord32" private : Int8.t -> Word32.t; val extdToWord64 = _import "WordS8_extdToWord64" private : Int8.t -> Word64.t; @@ -1280,18 +1281,17 @@ val gt = _import "WordS8_gt" private : Int8.t * Int8.t -> Bool.t; val le = _import "WordS8_le" private : Int8.t * Int8.t -> Bool.t; val lt = _import "WordS8_lt" private : Int8.t * Int8.t -> Bool.t; val mul = _import "WordS8_mul" private : Int8.t * Int8.t -> Int8.t; -val mulCheckOverflows = _import "WordS8_mulCheckOverflows" private : Int8.t * Int8.t -> Bool.t; -val negCheckOverflows = _import "WordS8_negCheckOverflows" private : Int8.t -> Bool.t; +val mulCheckP = _import "WordS8_mulCheckP" private : Int8.t * Int8.t -> Bool.t; val quot = _import "WordS8_quot" private : Int8.t * Int8.t -> Int8.t; val rem = _import "WordS8_rem" private : Int8.t * Int8.t -> Int8.t; val rndToReal32 = _import "WordS8_rndToReal32" private : Int8.t -> Real32.t; val rndToReal64 = _import "WordS8_rndToReal64" private : Int8.t -> Real64.t; val rshift = _import "WordS8_rshift" private : Int8.t * Word32.t -> Int8.t; -val subCheckOverflows = _import "WordS8_subCheckOverflows" private : Int8.t * Int8.t -> Bool.t; +val subCheckP = _import "WordS8_subCheckP" private : Int8.t * Int8.t -> Bool.t; end structure WordU16 = struct -val addCheckOverflows = _import "WordU16_addCheckOverflows" private : Word16.t * Word16.t -> Bool.t; +val addCheckP = _import "WordU16_addCheckP" private : Word16.t * Word16.t -> Bool.t; val extdToWord16 = _import "WordU16_extdToWord16" private : Word16.t -> Word16.t; val extdToWord32 = _import "WordU16_extdToWord32" private : Word16.t -> Word32.t; val extdToWord64 = _import "WordU16_extdToWord64" private : Word16.t -> Word64.t; @@ -1301,7 +1301,7 @@ val gt = _import "WordU16_gt" private : Word16.t * Word16.t -> Bool.t; val le = _import "WordU16_le" private : Word16.t * Word16.t -> Bool.t; val lt = _import "WordU16_lt" private : Word16.t * Word16.t -> Bool.t; val mul = _import "WordU16_mul" private : Word16.t * Word16.t -> Word16.t; -val mulCheckOverflows = _import "WordU16_mulCheckOverflows" private : Word16.t * Word16.t -> Bool.t; +val mulCheckP = _import "WordU16_mulCheckP" private : Word16.t * Word16.t -> Bool.t; val quot = _import "WordU16_quot" private : Word16.t * Word16.t -> Word16.t; val rem = _import "WordU16_rem" private : Word16.t * Word16.t -> Word16.t; val rndToReal32 = _import "WordU16_rndToReal32" private : Word16.t -> Real32.t; @@ -1310,7 +1310,7 @@ val rshift = _import "WordU16_rshift" private : Word16.t * Word32.t -> Word16.t; end structure WordU32 = struct -val addCheckOverflows = _import "WordU32_addCheckOverflows" private : Word32.t * Word32.t -> Bool.t; +val addCheckP = _import "WordU32_addCheckP" private : Word32.t * Word32.t -> Bool.t; val extdToWord16 = _import "WordU32_extdToWord16" private : Word32.t -> Word16.t; val extdToWord32 = _import "WordU32_extdToWord32" private : Word32.t -> Word32.t; val extdToWord64 = _import "WordU32_extdToWord64" private : Word32.t -> Word64.t; @@ -1320,7 +1320,7 @@ val gt = _import "WordU32_gt" private : Word32.t * Word32.t -> Bool.t; val le = _import "WordU32_le" private : Word32.t * Word32.t -> Bool.t; val lt = _import "WordU32_lt" private : Word32.t * Word32.t -> Bool.t; val mul = _import "WordU32_mul" private : Word32.t * Word32.t -> Word32.t; -val mulCheckOverflows = _import "WordU32_mulCheckOverflows" private : Word32.t * Word32.t -> Bool.t; +val mulCheckP = _import "WordU32_mulCheckP" private : Word32.t * Word32.t -> Bool.t; val quot = _import "WordU32_quot" private : Word32.t * Word32.t -> Word32.t; val rem = _import "WordU32_rem" private : Word32.t * Word32.t -> Word32.t; val rndToReal32 = _import "WordU32_rndToReal32" private : Word32.t -> Real32.t; @@ -1329,7 +1329,7 @@ val rshift = _import "WordU32_rshift" private : Word32.t * Word32.t -> Word32.t; end structure WordU64 = struct -val addCheckOverflows = _import "WordU64_addCheckOverflows" private : Word64.t * Word64.t -> Bool.t; +val addCheckP = _import "WordU64_addCheckP" private : Word64.t * Word64.t -> Bool.t; val extdToWord16 = _import "WordU64_extdToWord16" private : Word64.t -> Word16.t; val extdToWord32 = _import "WordU64_extdToWord32" private : Word64.t -> Word32.t; val extdToWord64 = _import "WordU64_extdToWord64" private : Word64.t -> Word64.t; @@ -1339,7 +1339,7 @@ val gt = _import "WordU64_gt" private : Word64.t * Word64.t -> Bool.t; val le = _import "WordU64_le" private : Word64.t * Word64.t -> Bool.t; val lt = _import "WordU64_lt" private : Word64.t * Word64.t -> Bool.t; val mul = _import "WordU64_mul" private : Word64.t * Word64.t -> Word64.t; -val mulCheckOverflows = _import "WordU64_mulCheckOverflows" private : Word64.t * Word64.t -> Bool.t; +val mulCheckP = _import "WordU64_mulCheckP" private : Word64.t * Word64.t -> Bool.t; val quot = _import "WordU64_quot" private : Word64.t * Word64.t -> Word64.t; val rem = _import "WordU64_rem" private : Word64.t * Word64.t -> Word64.t; val rndToReal32 = _import "WordU64_rndToReal32" private : Word64.t -> Real32.t; @@ -1348,7 +1348,7 @@ val rshift = _import "WordU64_rshift" private : Word64.t * Word32.t -> Word64.t; end structure WordU8 = struct -val addCheckOverflows = _import "WordU8_addCheckOverflows" private : Word8.t * Word8.t -> Bool.t; +val addCheckP = _import "WordU8_addCheckP" private : Word8.t * Word8.t -> Bool.t; val extdToWord16 = _import "WordU8_extdToWord16" private : Word8.t -> Word16.t; val extdToWord32 = _import "WordU8_extdToWord32" private : Word8.t -> Word32.t; val extdToWord64 = _import "WordU8_extdToWord64" private : Word8.t -> Word64.t; @@ -1358,7 +1358,7 @@ val gt = _import "WordU8_gt" private : Word8.t * Word8.t -> Bool.t; val le = _import "WordU8_le" private : Word8.t * Word8.t -> Bool.t; val lt = _import "WordU8_lt" private : Word8.t * Word8.t -> Bool.t; val mul = _import "WordU8_mul" private : Word8.t * Word8.t -> Word8.t; -val mulCheckOverflows = _import "WordU8_mulCheckOverflows" private : Word8.t * Word8.t -> Bool.t; +val mulCheckP = _import "WordU8_mulCheckP" private : Word8.t * Word8.t -> Bool.t; val quot = _import "WordU8_quot" private : Word8.t * Word8.t -> Word8.t; val rem = _import "WordU8_rem" private : Word8.t * Word8.t -> Word8.t; val rndToReal32 = _import "WordU8_rndToReal32" private : Word8.t -> Real32.t;