diff --git a/lib/netu.nix b/lib/netu.nix index 7bf0fed..cbbbb02 100644 --- a/lib/netu.nix +++ b/lib/netu.nix @@ -460,112 +460,7 @@ let bit = let - lut = [ - 1 # 0 - 2 # 1 - 4 # 2 - 8 # 3 - 16 # 4 - 32 # 5 - 64 # 6 - 128 # 7 - 256 # 8 - 512 # 9 - 1024 # 10 - 2048 # 11 - 4096 # 12 - 8192 # 13 - 16384 # 14 - 32768 # 15 - 65536 # 16 - 131072 # 17 - 262144 # 18 - 524288 # 19 - 1048576 # 20 - 2097152 # 21 - 4194304 # 22 - 8388608 # 23 - 16777216 # 24 - 33554432 # 25 - 67108864 # 26 - 134217728 # 27 - 268435456 # 28 - 536870912 # 29 - 1073741824 # 30 - 2147483648 # 31 - 4294967296 # 32 - 8589934592 # 33 - 17179869184 # 34 - 34359738368 # 35 - 68719476736 # 36 - 137438953472 # 37 - 274877906944 # 38 - 549755813888 # 39 - 1099511627776 # 40 - 2199023255552 # 41 - 4398046511104 # 42 - 8796093022208 # 43 - 17592186044416 # 44 - 35184372088832 # 45 - 70368744177664 # 46 - 140737488355328 # 47 - 281474976710656 # 48 - 562949953421312 # 49 - 1125899906842624 # 50 - 2251799813685248 # 51 - 4503599627370496 # 52 - 9007199254740992 # 53 - 18014398509481984 # 54 - 36028797018963968 # 55 - 72057594037927936 # 56 - 144115188075855872 # 57 - 288230376151711744 # 58 - 576460752303423488 # 59 - 1152921504606846976 # 60 - 2305843009213693952 # 61 - 4611686018427387904 # 62 - ]; - intmin = (-9223372036854775807) - 1; - intmax = 9223372036854775807; - left = - a: b: - if a >= 64 then - # It's allowed to shift out all bits - 0 - else if a == 0 then - b - else if a < 0 then - right (-a) b - else - let - inv = 63 - a; - mask = if inv == 63 then intmax else (builtins.elemAt lut inv) - 1; - masked = and b mask; - checker = if inv == 63 then intmin else builtins.elemAt lut inv; - negate = (and b checker) != 0; - mult = if a == 63 then intmin else builtins.elemAt lut a; - result = masked * mult; - in - if !negate then result else intmin + result; - - right = - a: b: - if a >= 64 then - 0 - else if a == 0 then - b - else if a < 0 then - left (-a) b - else - let - masked = and b intmax; - negate = b < 0; - result = masked / 2 / (builtins.elemAt lut (a - 1)); - inv = 63 - a; - highest_bit = builtins.elemAt lut inv; - in - if !negate then result else result + highest_bit; - + inherit (import ./shift.nix) left right; and = builtins.bitAnd; or = builtins.bitOr; diff --git a/lib/shift.nix b/lib/shift.nix new file mode 100644 index 0000000..333ce13 --- /dev/null +++ b/lib/shift.nix @@ -0,0 +1,112 @@ +let + # lut = [ + # 1 # 0 + # 2 # 1 + # 4 # 2 + # 8 # 3 + # 16 # 4 + # 32 # 5 + # 64 # 6 + # 128 # 7 + # 256 # 8 + # 512 # 9 + # 1024 # 10 + # 2048 # 11 + # 4096 # 12 + # 8192 # 13 + # 16384 # 14 + # 32768 # 15 + # 65536 # 16 + # 131072 # 17 + # 262144 # 18 + # 524288 # 19 + # 1048576 # 20 + # 2097152 # 21 + # 4194304 # 22 + # 8388608 # 23 + # 16777216 # 24 + # 33554432 # 25 + # 67108864 # 26 + # 134217728 # 27 + # 268435456 # 28 + # 536870912 # 29 + # 1073741824 # 30 + # 2147483648 # 31 + # 4294967296 # 32 + # 8589934592 # 33 + # 17179869184 # 34 + # 34359738368 # 35 + # 68719476736 # 36 + # 137438953472 # 37 + # 274877906944 # 38 + # 549755813888 # 39 + # 1099511627776 # 40 + # 2199023255552 # 41 + # 4398046511104 # 42 + # 8796093022208 # 43 + # 17592186044416 # 44 + # 35184372088832 # 45 + # 70368744177664 # 46 + # 140737488355328 # 47 + # 281474976710656 # 48 + # 562949953421312 # 49 + # 1125899906842624 # 50 + # 2251799813685248 # 51 + # 4503599627370496 # 52 + # 9007199254740992 # 53 + # 18014398509481984 # 54 + # 36028797018963968 # 55 + # 72057594037927936 # 56 + # 144115188075855872 # 57 + # 288230376151711744 # 58 + # 576460752303423488 # 59 + # 1152921504606846976 # 60 + # 2305843009213693952 # 61 + # 4611686018427387904 # 62 + # ]; + lut = builtins.foldl' (l: n: l ++ [ (2 * builtins.elemAt l n) ]) [ 1 ] (builtins.genList (x: x) 62); + intmin = (-9223372036854775807) - 1; + intmax = 9223372036854775807; + left = + a: b: + if a >= 64 then + # It's allowed to shift out all bits + 0 + else if a == 0 then + b + else if a < 0 then + right (-a) b + else + let + inv = 63 - a; + mask = if inv == 63 then intmax else (builtins.elemAt lut inv) - 1; + masked = builtins.bitAnd b mask; + checker = if inv == 63 then intmin else builtins.elemAt lut inv; + negate = (builtins.bitAnd b checker) != 0; + mult = if a == 63 then intmin else builtins.elemAt lut a; + result = masked * mult; + in + if !negate then result else intmin + result; + right = + a: b: + if a >= 64 then + 0 + else if a == 0 then + b + else if a < 0 then + left (-a) b + else + let + masked = builtins.bitAnd b intmax; + negate = b < 0; + # Split division to prevent having to divide by a negative number for + # shifts of 63 bit + result = masked / 2 / (builtins.elemAt lut (a - 1)); + inv = 63 - a; + highest_bit = builtins.elemAt lut inv; + in + if !negate then result else result + highest_bit; +in +{ + inherit left right; +}