1
1
Fork 1
mirror of https://github.com/oddlama/nixos-extra-modules.git synced 2025-10-10 13:50:39 +02:00

feat: move shift to separate file

feat: shorten implementation
This commit is contained in:
Patrick 2025-04-13 11:18:31 +02:00
parent 0875c4f06e
commit d04a0125d5
No known key found for this signature in database
GPG key ID: 451F95EFB8BECD0F
2 changed files with 113 additions and 106 deletions

View file

@ -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;

112
lib/shift.nix Normal file
View file

@ -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;
}