Created
January 13, 2013 05:28
-
-
Save anonymous/4522473 to your computer and use it in GitHub Desktop.
scratchpad for suggestions to add missing asm-like functionality to native ints in a perl6ish way.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# Trying to hash out perl6ish idioms for missing asm-like idioms. | |
# (things that end up ugly or non-very-optimizable using existing constructs) | |
# These would only be defined for native integer types. | |
# bit population counts | |
method leading(Bool(Any) $sense) # Count leading zeros/ones | |
method leading() # Count leading sign bits according to sign | |
method trailing(Bool(Any) $sense) # Count trailing zeros/ones | |
method count(Bool(Any) $sense) # Count zeros/ones population | |
method count() # sizeof * 8 (Count all bits) | |
# endianness conversion, bit reflection, permutations, frobbing | |
method reflect($width = 1) # like Buf.flip but bitwise/nybblewise/etc | |
method frob($mask) # lvalue Proxy-workalike for masked assign | |
method repack(:$width = 8, *@indices) # permute subfields | |
# :width selects bits/bitpairs/nybbles/bytes/words/etc. Is a power of two. | |
# additional coercives for non-sign-extended case | |
int16(int8 $a, :$unsigned!) # int16(int8(-1)) == int16(255) | |
uint16(int8 $a, :$unsigned!) # uint16(int8(-1)) == uint16(255) | |
int8.int16(:$unsigned!) | |
int8.uint16(:$unsigned!) | |
#...etc... | |
# adverbs to shift operations. | |
multi sub infix:«+<» (int $a, uint(Any) $bits, Bool :$rot!, :$c) { } | |
multi sub infix:«+<» (int $a, uint(Any) $bits, Bool :$rot!, :$c is rw) { } | |
multi sub infix:«+<» (int $a, uint(Any) $bits, :$c! is rw) { } | |
multi sub infix:«+>» (int $a, uint(Any) $bits, Bool :$rot!, :$c) { } | |
multi sub infix:«+>» (int $a, uint(Any) $bits, Bool :$rot!, :$c is rw) { } | |
multi sub infix:«+>» (int $a, uint(Any) $bits, :$c! is rw) { } | |
# :rot causes a barrel roll instead of a shift | |
# :c(0) (or :!c) allows logical (versus arithmatic) shifts | |
# :c($var) allow carry-bit emulation when $var is Bool. | |
# If you use $c, you can just write :$c. | |
# :c($var) using a type that can contain multiple bits allows remainder | |
# note that this treats $var as having as many bits as were shifted | |
# and zeros the other bits. | |
# so: $x = 6; $y = uint8(0x45) +> 4 :c($x); # $y = 0x64 and $x = 0x5 | |
# Adverbs to arithmetic operations: saturation and carry bit emulation | |
multi sub infix:<+> (int $a, int $b, :$sat!, :$c) { } | |
multi sub infix:<+> (int $a, int $b, :$sat!, :$c is rw) { } | |
multi sub infix:<+> (int $a, int $b, :$c!) { } | |
multi sub infix:<+> (int $a, int $b, :$c! is rw) { } | |
# ... | |
# When either :sat or :c is specified, result will be the same type as $a | |
# :sat causes saturation (clamping) addition/subtraction/multiplication/etc | |
# :$c gets carry bit on additions (or bits in the case of int16 + int8 :$c) | |
# for + and * :$c is added to $a before performing operation | |
# for / and - :$c works as a borrow |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment