Skip to content

Commit

Permalink
implement remining int fns
Browse files Browse the repository at this point in the history
Signed-off-by: Jiexiang Liu <[email protected]>
  • Loading branch information
jiex-liu committed Jun 29, 2024
1 parent 9cf3a83 commit 471d897
Show file tree
Hide file tree
Showing 2 changed files with 85 additions and 4 deletions.
55 changes: 51 additions & 4 deletions stdlib/src/bit/bit.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,19 @@ fn countr_zero[
# ===----------------------------------------------------------------------===#
# bit_reverse
# ===----------------------------------------------------------------------===#
# TODO: implement bit_reverse for Int type


@always_inline("nodebug")
fn bit_reverse(val: Int) -> Int:
"""Reverses the bitpattern of an integer value.
Args:
val: The input value.
Returns:
The input value with its bitpattern reversed.
"""
return llvm_intrinsic["llvm.bitreverse", Int, has_side_effect=False](val)


@always_inline("nodebug")
Expand Down Expand Up @@ -145,7 +157,31 @@ fn bit_reverse[
# ===----------------------------------------------------------------------===#
# byte_swap
# ===----------------------------------------------------------------------===#
# TODO: implement byte_swap for Int type


@always_inline("nodebug")
fn byte_swap(val: Int) -> Int:
"""Byte-swaps an integer value with an even number of bytes.
Byte swap an integer value with an even number of bytes (positive multiple
of 16 bits). This is equivalent to `llvm.bswap` intrinsic that has the
following semantics:
The `llvm.bswap.i16` intrinsic returns an i16 value that has the high and
low byte of the input i16 swapped. Similarly, the `llvm.bswap.i32` intrinsic
returns an i32 value that has the four bytes of the input i32 swapped, so
that if the input bytes are numbered 0, 1, 2, 3 then the returned i32 will
have its bytes in 3, 2, 1, 0 order. The `llvm.bswap.i48`, `llvm.bswap.i64`
and other intrinsics extend this concept to additional even-byte lengths (6
bytes, 8 bytes and more, respectively).
Args:
val: The input value.
Returns:
The input value with its bytes swapped.
"""
return llvm_intrinsic["llvm.bswap", Int, has_side_effect=False](val)


@always_inline("nodebug")
Expand Down Expand Up @@ -190,7 +226,19 @@ fn byte_swap[
# ===----------------------------------------------------------------------===#
# pop_count
# ===----------------------------------------------------------------------===#
# TODO: implement pop_count for Int type


@always_inline("nodebug")
fn pop_count(val: Int) -> Int:
"""Counts the number of bits set in an integer value.
Args:
val: The input value.
Returns:
The number of bits set in the input value.
"""
return llvm_intrinsic["llvm.ctpop", Int, has_side_effect=False](val)


@always_inline("nodebug")
Expand Down Expand Up @@ -222,7 +270,6 @@ fn pop_count[
# ===----------------------------------------------------------------------===#
# bit_not
# ===----------------------------------------------------------------------===#
# TODO: implement bit_not for Int type


@always_inline("nodebug")
Expand Down
34 changes: 34 additions & 0 deletions stdlib/test/bit/test_bit.mojo
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,16 @@ def test_countr_zero_simd():
assert_equal(countr_zero(var7), SIMD[int64_t, simd_width](62, 64, 0, 62))


def test_bit_reverse():
assert_equal(bit_reverse(-(2**32)), 4294967295)
assert_equal(bit_reverse(-1), -1)
assert_equal(bit_reverse(0), 0)
assert_equal(bit_reverse(1), -9223372036854775808)
assert_equal(bit_reverse(2), 4611686018427387904)
assert_equal(bit_reverse(3), -4611686018427387904)
assert_equal(bit_reverse(2**63), 1)


def test_bit_reverse_simd():
alias simd_width = 4
alias int8_t = DType.int8
Expand Down Expand Up @@ -134,6 +144,16 @@ def test_bit_reverse_simd():
)


def test_byte_swap():
assert_equal(byte_swap(0x0000), 0x0000000000000000)
assert_equal(byte_swap(0x0102), 0x0201000000000000)
assert_equal(byte_swap(0x0201), 0x0102000000000000)
assert_equal(byte_swap(-0x0123456789ABCDEF), 0x1132547698BADCFE)
assert_equal(byte_swap(0x0000000001234567), 0x6745230100000000)
assert_equal(byte_swap(0x56789ABCDEF01234), 0x3412F0DEBC9A7856)
assert_equal(byte_swap(0x23456789ABCDEF01), 0x01EFCDAB89674523)


def test_byte_swap_simd():
alias simd_width = 4
alias int16_t = DType.int16
Expand Down Expand Up @@ -173,6 +193,17 @@ def test_byte_swap_simd():
)


def test_pop_count():
assert_equal(pop_count(-111444444), 51)
assert_equal(pop_count(0), 0)
assert_equal(pop_count(1), 1)
assert_equal(pop_count(2), 1)
assert_equal(pop_count(3), 2)
assert_equal(pop_count(4), 1)
assert_equal(pop_count(5), 2)
assert_equal(pop_count(3000000), 10)


def test_pop_count_simd():
alias simd_width = 4
alias int8_t = DType.int8
Expand Down Expand Up @@ -457,7 +488,10 @@ def main():
test_countl_zero_simd()
test_countr_zero()
test_countr_zero_simd()
test_bit_reverse()
test_bit_reverse_simd()
test_byte_swap()
test_byte_swap_simd()
test_pop_count()
test_pop_count_simd()
test_bit_not_simd()

0 comments on commit 471d897

Please sign in to comment.