Skip to content

Instantly share code, notes, and snippets.

@skids
Last active December 14, 2015 00:19
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save skids/4998260 to your computer and use it in GitHub Desktop.
Save skids/4998260 to your computer and use it in GitHub Desktop.
possible asm-like methods for native types in Perl6
This is just food for thought/spit-balling. Most methods would only be available across the various native int/uint/buf types and NSA.
# bit population counts (note that this is not .msb, which is implemented as 1's compliment)
method bitslead(Bool(Any) $sense) # Count leading zeros/ones
method bitslead() # Count leading sign bits according to sign
method bitstrail(Bool(Any) $sense) # Count trailing zeros/ones
method bitcount(Bool(Any) $sense) # Count zeros/ones population
method bitcount() # 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 coercive multis for non-sign-extended case
int16(int8 $a, :$signed!) # int16(int8(-1)) == int16(255)
uint16(int8 $a, :$signed!) # uint16(int8(-1)) == uint16(255)
int8.int16(:$signed!)
int8.uint16(:$signed!)
# ...
# adverbs to shift operations and rotate ops
multi sub infix:«+>» (int $a, Int(Any) $bits, :$c, :$signed) { }
multi sub infix:«⥁» (int $a, Int(Any) $bits, :$c is rw, :$signed) { }
multi sub infix:«^>» (int $a, Int(Any) $bits, :$c is rw, :$signed) { } # Texas ⥁
multi sub infix:«+<» (int $a, Int(Any) $bits, :$c, :$signed) { }
multi sub infix:«^<» (int $a, Int(Any) $bits, :$c is rw, :$signed) { } # Texas ⥀
multi sub infix:«⥀» (int $a, Int(Any) $bits, :$c is rw, :$signed) { }
# ... for other left hand types.
# :c($var) allow carry-bit emulation when $var is Bool.
# If you use "my $c" for carry, 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 int8 + int16 :$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