Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

pure rust implementation of the CTPOP population count instruction

  • Loading branch information...
commit c5286f2f60eb4d919e422fbc4759a6909f2e76dd 1 parent 63a138a
@stevej authored
Showing with 43 additions and 0 deletions.
  1. +2 −0  README.md
  2. +1 −0  crate.rc
  3. +40 −0 ctpop.rs
View
2  README.md
@@ -7,3 +7,5 @@
`tree.rs` - A purely functional binary search tree. Currently lacks delete.
`red_black_tree.rs` - A purely functional red-black tree.
+
+`ctpop.rs` - A Rust implementation of the population count (native CTPOP instruction)
View
1  crate.rc
@@ -21,5 +21,6 @@ pub mod tree;
pub mod lazy;
pub mod pairing_heap;
pub mod red_black_tree;
+pub mod ctpop;
mod test_tree;
View
40 ctpop.rs
@@ -0,0 +1,40 @@
+/**
+ * Count the Population of an unsigned integer. Returns how many bits are
+ * set to 1.
+ *
+ * Currently designed for a 32-bit unsigned integer.
+ *
+ * Many chips have a CTPOP instruction available and would be an order
+ * of magnitude speed improvement.
+ */
+pure fn ctpop32(map : u32) -> u32 {
+ // Code smell: these constants should not be defined in the function.
+ let SK5 : u32 = 0x55555555;
+ let SK3 : u32 = 0x33333333;
+ let SKF0 : u32 = 0xF0F0F0F;
+ let SKFF : u32 = 0xFF00FF;
+ let mut Map = copy map;
+
+ Map-=((Map>>1)&SK5);
+ Map=(Map&SK3)+((Map>>2)&SK3);
+ Map=(Map&SKF0)+((Map>>4)&SKF0);
+ Map+=Map>>8;
+
+ return (Map+(Map>>16))&0x3F;
+}
+
+#[test]
+fn test_ctpop32() {
+ assert(ctpop32(0x0) == 0);
+ assert(ctpop32(0x1) == 1);
+ assert(ctpop32(0x3) == 2);
+ assert(ctpop32(0x7) == 3);
+ assert(ctpop32(0xF) == 4);
+ assert(ctpop32(0x10) == 1);
+ assert(ctpop32(0xFF) == 8);
+ assert(ctpop32(0xAD) == 5);
+ assert(ctpop32(0x2FADBFF) == 21);
+ assert(ctpop32(0x82FFFFFF) == 26);
+ assert(ctpop32(0x8FFFFFFF) == 29);
+ assert(ctpop32(0xFFFFFFFF) == 32);
+}
Please sign in to comment.
Something went wrong with that request. Please try again.