Skip to content

Commit

Permalink
Implement the clz function (#957)
Browse files Browse the repository at this point in the history
  • Loading branch information
dfellis authored Nov 13, 2024
1 parent 0a3cecb commit aba5ac1
Show file tree
Hide file tree
Showing 2 changed files with 110 additions and 0 deletions.
81 changes: 81 additions & 0 deletions alan/src/compile/integration_tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -610,6 +610,15 @@ test_full!(i8_abs => r#"
export fn main = print(abs(i8(-3)));"#;
stdout "3\n";
);
test_full!(i8_clz => r#"
export fn main {
0.i8.clz.print;
1.i8.clz.print;
2.i8.clz.print;
(-128).i8.clz.print;
}"#;
stdout "8\n7\n6\n0\n";
);

test_full!(i16_add => r#"
export fn main {
Expand Down Expand Up @@ -667,6 +676,15 @@ test_full!(i16_abs => r#"
export fn main = print(i16(-3).abs);"#;
stdout "3\n";
);
test_full!(i16_clz => r#"
export fn main {
0.i16.clz.print;
1.i16.clz.print;
2.i16.clz.print;
(-32768).i16.clz.print;
}"#;
stdout "16\n15\n14\n0\n";
);

test_full!(i32_add => r#"
export fn main {
Expand Down Expand Up @@ -724,6 +742,15 @@ test_full!(i32_abs => r#"
export fn main = print(-3.i32.abs);"#;
stdout "3\n";
);
test_full!(i32_clz => r#"
export fn main {
0.i32.clz.print;
1.i32.clz.print;
2.i32.clz.print;
(-2_147_483_648).i32.clz.print;
}"#;
stdout "32\n31\n30\n0\n";
);

test_full!(i64_add => r#"
export fn main = print(1 + 2);"#;
Expand Down Expand Up @@ -765,6 +792,15 @@ test_full!(i64_abs => r#"
export fn main = print(-3.abs);"#;
stdout "3\n";
);
test_full!(i64_clz => r#"
export fn main {
0.clz.print;
1.clz.print;
2.clz.print;
(-9_223_372_036_854_775_808).clz.print;
}"#;
stdout "64\n63\n62\n0\n";
);

test_full!(u8_add => r#"
export fn main() -> ExitCode = ExitCode(add(u8(1), u8(2)));"#;
Expand Down Expand Up @@ -802,6 +838,15 @@ test_full!(u8_max => r#"
}"#;
stdout "5\n";
);
test_full!(u8_clz => r#"
export fn main {
0.u8.clz.print;
1.u8.clz.print;
2.u8.clz.print;
255.u8.clz.print;
}"#;
stdout "8\n7\n6\n0\n";
);

test_full!(u16_add => r#"
export fn main {
Expand Down Expand Up @@ -851,6 +896,15 @@ test_full!(u16_max => r#"
}"#;
stdout "5\n";
);
test_full!(u16_clz => r#"
export fn main {
0.u16.clz.print;
1.u16.clz.print;
2.u16.clz.print;
65535.u16.clz.print;
}"#;
stdout "16\n15\n14\n0\n";
);

test_full!(u32_add => r#"
export fn main {
Expand Down Expand Up @@ -900,6 +954,15 @@ test_full!(u32_max => r#"
}"#;
stdout "5\n";
);
test_full!(u32_clz => r#"
export fn main {
0.u32.clz.print;
1.u32.clz.print;
2.u32.clz.print;
2_147_483_648.u32.clz.print;
}"#;
stdout "32\n31\n30\n0\n";
);

test_full!(u64_add => r#"
export fn main = print(1.u64 + 2.u64);"#;
Expand Down Expand Up @@ -933,6 +996,16 @@ test_full!(u64_max => r#"
export fn main = max(3.u64, 5.u64).print;"#;
stdout "5\n";
);
test_full!(u64_clz => r#"
export fn main {
0.u64.clz.print;
1.u64.clz.print;
2.u64.clz.print;
// TODO: Fix u64 integer representation in the compiler
// 9_223_372_036_854_775_808.u64.clz.print;
}"#;
stdout "64\n63\n62\n";
);

test_full!(f32_add => r#"
export fn main {
Expand Down Expand Up @@ -1181,6 +1254,14 @@ test_gpgpu!(gpu_abs => r#"
stdout "[1, 2, 3, 4]\n";
);

test_gpgpu!(gpu_clz => r#"
export fn main {
let b = GBuffer([1.i32, -2.i32, -3.i32, 4.i32]);
b.map(fn (val: gi32) = val.clz).read{i32}.print;
}"#;
stdout "[31, 0, 0, 29]\n";
);

// Bitwise Math

test_full!(i8_bitwise => r#"
Expand Down
29 changes: 29 additions & 0 deletions alan/src/std/root.ln
Original file line number Diff line number Diff line change
Expand Up @@ -548,6 +548,8 @@ export fn{Rs} wrl (a: i8, b: i8) = {Method{"rotate_left"} :: (i8, Deref{u32}) ->
export fn{Js} wrl Method{"rotateLeft"} :: (i8, i8) -> i8;
export fn{Rs} wrr (a: i8, b: i8) = {Method{"rotate_right"} :: (i8, Deref{u32}) -> i8}(a, b.u32);
export fn{Js} wrr Method{"rotateRight"} :: (i8, i8) -> i8;
export fn{Rs} clz (a: i8) = {Method{"leading_zeros"} :: i8 -> u32}(a).i8;
export fn{Js} clz Method{"clz"} :: i8 -> i8;

export fn{Rs} add Method{"wrapping_add"} :: (i16, Deref{i16}) -> i16;
export fn{Js} add Method{"wrappingAdd"} :: (i16, i16) -> i16;
Expand Down Expand Up @@ -599,6 +601,8 @@ export fn{Rs} wrl (a: i16, b: i16) = {Method{"rotate_left"} :: (i16, Deref{u32})
export fn{Js} wrl Method{"rotateLeft"} :: (i16, i16) -> i16;
export fn{Rs} wrr (a: i16, b: i16) = {Method{"rotate_right"} :: (i16, Deref{u32}) -> i16}(a, b.u32);
export fn{Js} wrr Method{"rotateRight"} :: (i16, i16) -> i16;
export fn{Rs} clz (a: i16) = {Method{"leading_zeros"} :: i16 -> u32}(a).i16;
export fn{Js} clz Method{"clz"} :: i16 -> i16;

export fn{Rs} add Method{"wrapping_add"} :: (i32, Deref{i32}) -> i32;
export fn{Js} add Method{"wrappingAdd"} :: (i32, i32) -> i32;
Expand Down Expand Up @@ -650,6 +654,8 @@ export fn{Rs} wrl (a: i32, b: i32) = {Method{"rotate_left"} :: (i32, Deref{u32})
export fn{Js} wrl Method{"rotateLeft"} :: (i32, i32) -> i32;
export fn{Rs} wrr (a: i32, b: i32) = {Method{"rotate_right"} :: (i32, Deref{u32}) -> i32}(a, b.u32);
export fn{Js} wrr Method{"rotateRight"} :: (i32, i32) -> i32;
export fn{Rs} clz (a: i32) = {Method{"leading_zeros"} :: i32 -> u32}(a).i32;
export fn{Js} clz Method{"clz"} :: i32 -> i32;

export fn{Rs} add Method{"wrapping_add"} :: (i64, Deref{i64}) -> i64;
export fn{Js} add Method{"wrappingAdd"} :: (i64, i64) -> i64;
Expand Down Expand Up @@ -701,6 +707,8 @@ export fn{Rs} wrl (a: i64, b: i64) = {Method{"rotate_left"} :: (i64, Deref{u32})
export fn{Js} wrl Method{"rotateLeft"} :: (i64, i64) -> i64;
export fn{Rs} wrr (a: i64, b: i64) = {Method{"rotate_right"} :: (i64, Deref{u32}) -> i64}(a, b.u32);
export fn{Js} wrr Method{"rotateRight"} :: (i64, i64) -> i64;
export fn{Rs} clz (a: i64) = {Method{"leading_zeros"} :: i64 -> u32}(a).i64;
export fn{Js} clz Method{"clz"} :: i64 -> i64;

/// Unsigned Integer-related functions and function bindings
export fn{Rs} add Method{"wrapping_add"} :: (u8, Deref{u8}) -> u8;
Expand Down Expand Up @@ -749,6 +757,8 @@ export fn{Rs} wrl (a: u8, b: u8) = {Method{"rotate_left"} :: (u8, Deref{u32}) ->
export fn{Js} wrl Method{"rotateLeft"} :: (u8, u8) -> u8;
export fn{Rs} wrr (a: u8, b: u8) = {Method{"rotate_right"} :: (u8, Deref{u32}) -> u8}(a, b.u32);
export fn{Js} wrr Method{"rotateRight"} :: (u8, u8) -> u8;
export fn{Rs} clz (a: u8) = {Method{"leading_zeros"} :: u8 -> u32}(a).u8;
export fn{Js} clz Method{"clz"} :: u8 -> u8;

export fn{Rs} add Method{"wrapping_add"} :: (u16, Deref{u16}) -> u16;
export fn{Js} add Method{"wrappingAdd"} :: (u16, u16) -> u16;
Expand Down Expand Up @@ -796,6 +806,8 @@ export fn{Rs} wrl (a: u16, b: u16) = {Method{"rotate_left"} :: (u16, Deref{u32})
export fn{Js} wrl Method{"rotateLeft"} :: (u16, u16) -> u16;
export fn{Rs} wrr (a: u16, b: u16) = {Method{"rotate_right"} :: (u16, Deref{u32}) -> u16}(a, b.u32);
export fn{Js} wrr Method{"rotateRight"} :: (u16, u16) -> u16;
export fn{Rs} clz (a: u16) = {Method{"leading_zeros"} :: u16 -> u32}(a).u16;
export fn{Js} clz Method{"clz"} :: u16 -> u16;

export fn{Rs} add Method{"wrapping_add"} :: (u32, Deref{u32}) -> u32;
export fn{Js} add Method{"wrappingAdd"} :: (u32, u32) -> u32;
Expand Down Expand Up @@ -843,6 +855,8 @@ export fn{Rs} wrl (a: u32, b: u32) = {Method{"rotate_left"} :: (u32, Deref{u32})
export fn{Js} wrl Method{"rotateLeft"} :: (u32, u32) -> u32;
export fn{Rs} wrr (a: u32, b: u32) = {Method{"rotate_right"} :: (u32, Deref{u32}) -> u32}(a, b.u32);
export fn{Js} wrr Method{"rotateRight"} :: (u32, u32) -> u32;
export fn{Rs} clz Method{"leading_zeros"} :: u32 -> u32;
export fn{Js} clz Method{"clz"} :: u32 -> u32;

export fn{Rs} add Method{"wrapping_add"} :: (u64, Deref{u64}) -> u64;
export fn{Js} add Method{"wrappingAdd"} :: (u64, u64) -> u64;
Expand Down Expand Up @@ -890,6 +904,8 @@ export fn{Rs} wrl (a: u64, b: u64) = {Method{"rotate_left"} :: (u64, Deref{u32})
export fn{Js} wrl Method{"rotateLeft"} :: (u64, u64) -> u64;
export fn{Rs} wrr (a: u64, b: u64) = {Method{"rotate_right"} :: (u64, Deref{u32}) -> u64}(a, b.u32);
export fn{Js} wrr Method{"rotateRight"} :: (u64, u64) -> u64;
export fn{Rs} clz (a: u64) = {Method{"leading_zeros"} :: u64 -> u32}(a).u64;
export fn{Js} clz Method{"clz"} :: u64 -> u64;

/// Float-related functions and function bindings
export fn{Rs} add Infix{"+"} :: (f32, f32) -> f32;
Expand Down Expand Up @@ -3619,6 +3635,19 @@ export fn abs(v: gvec3f) = gabs{gvec3f}(v);
export fn abs(v: gvec4i) = gabs{gvec4i}(v);
export fn abs(v: gvec4f) = gabs{gvec4f}(v);

fn gclz{I}(v: I) {
let varName = 'countLeadingZeros('.concat(v.varName).concat(')');
return {I}(varName, v.statements, v.buffers);
}
export fn clz(v: gi32) = gclz{gi32}(v);
export fn clz(v: gu32) = gclz{gu32}(v);
export fn clz(v: gvec2i) = gclz{gvec2i}(v);
export fn clz(v: gvec2u) = gclz{gvec2u}(v);
export fn clz(v: gvec3i) = gclz{gvec3i}(v);
export fn clz(v: gvec3u) = gclz{gvec3u}(v);
export fn clz(v: gvec4i) = gclz{gvec4i}(v);
export fn clz(v: gvec4u) = gclz{gvec4u}(v);

fn gadd{A, B}(a: A, b: B) {
let varName = '('.concat(a.varName).concat(' + ').concat(b.varName).concat(')');
let statements = a.statements.concat(b.statements);
Expand Down

0 comments on commit aba5ac1

Please sign in to comment.