arxpy.bitvector.extraop module

Provide additional bit-vector operators.

arxpy.bitvector.extraop.repeat_pattern(pattern, width)[source]

Repeat the pattern until obtain a bit-vector of given width.

arxpy.bitvector.extraop.pattern01(width)[source]

Obtain the pattern 0…01…1 with given 0-width.

class arxpy.bitvector.extraop.PopCount[source]

Bases: arxpy.bitvector.operation.Operation

Count the number of 1’s in the bit-vector.

This operation is also known as the hamming weight of a bit-vector.

>>> from arxpy.bitvector.core import Constant, Variable
>>> from arxpy.bitvector.extraop import PopCount
>>> PopCount(Constant(0b1010, 4))
0b010
>>> PopCount(Constant(0b101, 3))
0b10
>>> PopCount(Variable("x", 4))  
((0x3 & ((x - (0x5 & (x >> 0x1))) >> 0x2)) + (0x3 & (x - (0x5 & (x >> 0x1)))))[2:]
>>> PopCount(Variable("x", 3))  
(0b0 :: (x[0])) + (0b0 :: (x[1])) + (0b0 :: (x[2]))
classmethod output_width(x)[source]

Return the bit-width of the resulting bit-vector.

classmethod eval(bv)[source]

Evaluate the operator with given operands.

This is an internal method. To evaluate a bit-vector operation, use the operator ().

class arxpy.bitvector.extraop.Reverse[source]

Bases: arxpy.bitvector.operation.Operation

Reverse the bit-vector.

>>> from arxpy.bitvector.core import Constant, Variable
>>> from arxpy.bitvector.extraop import PopCount
>>> Reverse(Constant(0b1010, 4))
0x5
>>> Reverse(Constant(0b001, 3))
0b100
>>> Reverse(Variable("x", 4))  
(0x3 & (((0x5 & (x >> 0x1)) | ((0x5 & x) << 0x1)) >> 0x2)) |
((0x3 & ((0x5 & (x >> 0x1)) | ((0x5 & x) << 0x1))) << 0x2)
>>> Reverse(Variable("x", 3))  
(x[0]) :: (x[1]) :: (x[2])
classmethod output_width(x)[source]

Return the bit-width of the resulting bit-vector.

classmethod eval(bv)[source]

Evaluate the operator with given operands.

This is an internal method. To evaluate a bit-vector operation, use the operator ().

class arxpy.bitvector.extraop.PopCountSum2[source]

Bases: arxpy.bitvector.operation.Operation

Count the number of 1’s of two bit-vectors.

>>> from arxpy.bitvector.core import Constant, Variable
>>> from arxpy.bitvector.extraop import PopCountSum2
>>> PopCountSum2(Constant(0b000, 3), Constant(0b001, 3))
0b001
>>> PopCountSum2(~Constant(0, 15), ~Constant(0, 15))
0b11110
>>> PopCountSum2(Variable("x", 4), Variable("y", 4))  
(0x3 & ((x - (0x5 & (x >> 0x1))) >> 0x2)) + (0x3 & (x - (0x5 & (x >> 0x1)))) +
(0x3 & ((y - (0x5 & (y >> 0x1))) >> 0x2)) + (0x3 & (y - (0x5 & (y >> 0x1))))
>>> PopCountSum2(Variable("x", 3), Variable("y", 3))  
(0b0 :: ((0b0 :: (x[0])) + (0b0 :: (x[1])) + (0b0 :: (x[2])))) +
(0b0 :: ((0b0 :: (y[0])) + (0b0 :: (y[1])) + (0b0 :: (y[2]))))
classmethod condition(x, y)[source]

Check if the operands verify the restrictions of the operator.

classmethod output_width(x, y)[source]

Return the bit-width of the resulting bit-vector.

classmethod eval(x, y)[source]

Evaluate the operator with given operands.

This is an internal method. To evaluate a bit-vector operation, use the operator ().

class arxpy.bitvector.extraop.PopCountSum3[source]

Bases: arxpy.bitvector.operation.Operation

Count the number of 1’s of three bit-vectors.

>>> from arxpy.bitvector.core import Constant, Variable
>>> from arxpy.bitvector.extraop import PopCountSum3
>>> PopCountSum3(Constant(0b000, 3), Constant(0b001, 3), Constant(0b011, 3))
0x3
>>> PopCountSum3(Variable("x", 4), Variable("y", 4), Variable("z", 4))  
(0x3 & ((x - (0x5 & (x >> 0x1))) >> 0x2)) + (0x3 & (x - (0x5 & (x >> 0x1)))) +
(0x3 & ((y - (0x5 & (y >> 0x1))) >> 0x2)) + (0x3 & (y - (0x5 & (y >> 0x1)))) +
(0x3 & ((z - (0x5 & (z >> 0x1))) >> 0x2)) + (0x3 & (z - (0x5 & (z >> 0x1))))
>>> PopCountSum3(Variable("x", 3), Variable("y", 3), Constant(0, 3))  
(0b00 :: ((0b0 :: (x[0])) + (0b0 :: (x[1])) + (0b0 :: (x[2])))) +
(0b00 :: ((0b0 :: (y[0])) + (0b0 :: (y[1])) + (0b0 :: (y[2]))))
classmethod condition(x, y, z)[source]

Check if the operands verify the restrictions of the operator.

classmethod output_width(x, y, z)[source]

Return the bit-width of the resulting bit-vector.

classmethod eval(x, y, z)[source]

Evaluate the operator with given operands.

This is an internal method. To evaluate a bit-vector operation, use the operator ().

class arxpy.bitvector.extraop.PopCountDiff[source]

Bases: arxpy.bitvector.operation.Operation

Compute the difference of the hamming weight of two words

>>> from arxpy.bitvector.core import Constant, Variable
>>> from arxpy.bitvector.extraop import PopCountDiff
>>> PopCountDiff(Constant(0b011, 3), Constant(0b100, 3))
0b01
>>> PopCountDiff(Variable("x", 4), Variable("y", 4))  
(((0x3 & ((x - (0x5 & (x >> 0x1))) >> 0x2)) + (0x3 & (x - (0x5 & (x >> 0x1)))) +
(0x3 & ((~y - (0x5 & (~y >> 0x1))) >> 0x2)) + (0x3 & (~y - (0x5 & (~y >> 0x1))))) - 0x4)[2:]
>>> PopCountDiff(Variable("x", 3), Variable("y", 3))  
((0b0 :: (x[0])) + (0b0 :: (x[1])) + (0b0 :: (x[2]))) -
((0b0 :: (y[0])) + (0b0 :: (y[1])) + (0b0 :: (y[2])))
classmethod condition(x, y)[source]

Check if the operands verify the restrictions of the operator.

classmethod output_width(x, y)[source]

Return the bit-width of the resulting bit-vector.

classmethod eval(x, y)[source]

Evaluate the operator with given operands.

This is an internal method. To evaluate a bit-vector operation, use the operator ().

class arxpy.bitvector.extraop.LeadingZeros[source]

Bases: arxpy.bitvector.operation.Operation

Return a bit-vector with the leading zeros set to one and the rest to zero.

>>> from arxpy.bitvector.core import Constant, Variable
>>> from arxpy.bitvector.extraop import PopCount
>>> LeadingZeros(Constant(0b11111, 5))
0b00000
>>> LeadingZeros(Constant(0b001, 3))
0b110
>>> LeadingZeros(Variable("x", 4))  
~(((x | (x >> 0x1)) >> 0x2) | x | (x >> 0x1))
>>> LeadingZeros(Variable("x", 3))  
~((((((0b0 :: x) >> 0x1) | (0b0 :: x)) >> 0x2) | ((0b0 :: x) >> 0x1) | (0b0 :: x))[2:])
classmethod output_width(x)[source]

Return the bit-width of the resulting bit-vector.

classmethod eval(bv)[source]

Evaluate the operator with given operands.

This is an internal method. To evaluate a bit-vector operation, use the operator ().

class arxpy.bitvector.extraop.PartialOperation[source]

Bases: arxpy.bitvector.operation.Operation

Represent the bit-vector operations with fixed arguments.

arxpy.bitvector.extraop.make_partial_operation(bv_op, fixed_args)[source]

Return a new operation based on the given one but with fixed arguments.

The argument fixed_args is a tuple with the same length as the number of operands of the given function, containing None or Constant elements. If fixed_args[i] is None, the i-th operand is not fixed; otherwise, the i-th operand is replaced with fixed_args[i].

>>> from arxpy.bitvector.core import Constant, Variable
>>> from arxpy.bitvector.operation import BvAdd
>>> BvCteAdd = make_partial_operation(BvAdd, tuple([None, Constant(1, 4)]))
>>> BvCteAdd(Variable("a", 4))
BvAdd(·, 0x1)(a)
>>> BvCteAdd(Constant(1, 4))
0x2
>>> assert BvCteAdd == make_partial_operation(BvAdd, tuple([None, Constant(1, 4)]))