Package ghidra.app.plugin.assembler.sleigh.expr

# Class MaskedLong

java.lang.Object
ghidra.app.plugin.assembler.sleigh.expr.MaskedLong

All Implemented Interfaces:
  `Comparable<MaskedLong>`

public class MaskedLong extends Object implements Comparable<MaskedLong>
A `64`-bit value where each bit is `0`, `1`, or `x` (undefined)

- ## Field Summary

  Fields
  Modifier and Type
  Field
  Description
  `protected long`
  `msk`
  `static final MaskedLong`
  `ONES`
  `static final MaskedLong`
  `UNKS`
  `protected long`
  `val`
  `static final MaskedLong`
  `ZERO`

- ## Constructor Summary

  Constructors
  Modifier
  Constructor
  Description
  `protected`
  `MaskedLong(long msk, long val)`
  Create a masked long given a mask and value

- ## Method Summary

  Modifier and Type
  Method
  Description
  `MaskedLong`
  `add(MaskedLong that)`
  Compute the arithmetic sum of this and another masked long
  `boolean`
  `agrees(long that)`
  Checks if this and a long agree
  `boolean`
  `agrees(MaskedLong that)`
  Checks if this and another masked long agree
  `boolean`
  `agrees(Object that)`
  Check if this and another object agree
  `MaskedLong`
  `and(MaskedLong that)`
  Compute the bitwise AND of this and another masked long
  `MaskedLong`
  `byteSwap(int n)`
  Reverse the least significant `n` bytes
  `MaskedLong`
  `combine(MaskedLong that)`
  Combine this and another masked long into one, by taking defined bits from either
  `int`
  `compareTo(MaskedLong that)`
  "Compare" two masked longs
  `MaskedLong`
  `divideSigned(MaskedLong that)`
  `MaskedLong`
  `divideUnsigned(MaskedLong that)`
  Compute the unsigned arithmetic quotient: this masked long divided by another
  `boolean`
  `equals(Object other)`
  Check for equality
  `MaskedLong`
  `fillMask()`
  Set all undefined bits to 0
  `static MaskedLong`
  `fromLong(long val)`
  Create a fully-defined value from the bits of a long
  `static MaskedLong`
  `fromMaskAndValue(long msk, long val)`
  Create a masked value from a mask and a long
  `long`
  `getMask()`
  Get the mask as a long
  `int`
  `hashCode()`
  `MaskedLong`
  `invAnd(MaskedLong that)`
  Solves the expression `A & B = C, for B, given C and A`
  `MaskedLong`
  `invMultiplyUnsigned(MaskedLong that)`
  Compute the arithmetic quotient as a solution to unsigned multiplication
  `MaskedLong`
  `invOr(MaskedLong that)`
  Solves the expression A | B = C, for B, given C and A
  `MaskedLong`
  `invShiftLeft(long n)`
  Invert a left shift of `n` positions, that is shift right
  `MaskedLong`
  `invShiftLeft(MaskedLong n)`
  Invert a left shift of `n` positions, that is shift right
  `MaskedLong`
  `invShiftRight(long n)`
  Invert an arithmetic right shift of `n` positions, that is shift left
  `MaskedLong`
  `invShiftRight(MaskedLong n)`
  Invert an arithmetic right shift of `n` positions, that is shift left
  `MaskedLong`
  `invShiftRightLogical(long n)`
  Invert a logical right shift of `n` positions, that is shift left
  `MaskedLong`
  `invShiftRightLogical(MaskedLong n)`
  Invert a logical right shift of `n` positions, that is shift left
  `boolean`
  `isFullyDefined()`
  True iff there are no undefined bits
  `boolean`
  `isFullyUndefined()`
  True iff there are no defined bits
  `boolean`
  `isInRange(long max, boolean signed)`
  Check if the masked value falls within a given range
  `long`
  `longValue()`
  Obtain the value as a long, where all undefined bits are treated as `0`
  `MaskedLong`
  `mask(long mask)`
  Apply an additional mask to this masked long
  `MaskedLong`
  `multiply(MaskedLong that)`
  Compute the arithmetic product of this and another masked long
  `MaskedLong`
  `negate()`
  Negate the value
  `MaskedLong`
  `not()`
  Compute the bitwise NOT
  `MaskedLong`
  `or(MaskedLong that)`
  Compute the bitwise OR of this and another masked long
  `MaskedLong`
  `shiftCircular(long n, int size, int dir)`
  Shift `size` bits @{code n) positions circularly in a given direction
  `MaskedLong`
  `shiftCircular(MaskedLong n, int size, int dir)`
  Shift `size` bits @{code n) positions circularly in a given direction
  `MaskedLong`
  `shiftLeft(long n)`
  Shift the bits @{code n} positions left
  `MaskedLong`
  `shiftLeft(MaskedLong n)`
  Shift the bits `n` positions left
  `MaskedLong`
  `shiftRight(long n)`
  Shift the bits arithmetically `n` positions right
  `MaskedLong`
  `shiftRight(MaskedLong n)`
  Shift the bits arithmetically `n` positions right
  `MaskedLong`
  `shiftRightLogical(long n)`
  Shift the bits logically `n` positions right
  `MaskedLong`
  `shiftRightLogical(MaskedLong n)`
  Shift the bits logically `n` positions right
  `MaskedLong`
  `shiftRightPositional(long n)`
  Shift the bits positionally `n` positions right
  `MaskedLong`
  `signExtend()`
  Sign extend the masked value, according to its mask, to a full long
  `MaskedLong`
  `signExtend(int n)`
  Sign extend the masked value as if of the given size in bits, to a full long
  `protected static long`
  `signExtend(long val, int bits)`
  Sign extend a number of the given size in bits, to a full long
  `MaskedLong`
  `subtract(MaskedLong that)`
  Compute the arithmetic difference: this masked long minus another
  `String`
  `toString()`
  `MaskedLong`
  `unknownExtend(int n)`
  Mask out all but the lowest `n` bits of the value
  `MaskedLong`
  `xor(MaskedLong that)`
  Compute the bitwise XOR of this and another masked long
  `MaskedLong`
  `zeroExtend()`
  Zero extend the masked value, according to its mask, to a full long
  `MaskedLong`
  `zeroExtend(int n)`
  Zero extend the masked value as if of the given size in bits, to a full long
  `protected static long`
  `zeroExtend(long val, int bits)`
  Zero extend a number of the given size in bits, to a full long

  ### Methods inherited from class java.lang.Object

  `clone, finalize, getClass, notify, notifyAll, wait, wait, wait`

- ## Field Details

  - ### ZERO

    public static final MaskedLong ZERO

  - ### UNKS

    public static final MaskedLong UNKS

  - ### ONES

    public static final MaskedLong ONES

  - ### msk

    protected long msk

  - ### val

    protected long val

- ## Constructor Details

  - ### MaskedLong

    protected MaskedLong(long msk, long val)
    Create a masked long given a mask and value

- ## Method Details

  - ### fromMaskAndValue

    public static MaskedLong fromMaskAndValue(long msk, long val)
    Create a masked value from a mask and a long

    Any positions in `msk` set to 0 create an `x` in the corresponding position of the result. Otherwise, the position takes the corresponding bit from `val`.

    Parameters:
      `msk` - the mask
      `val` - the value
    Returns:
      the constructed masked long

  - ### fromLong

    public static MaskedLong fromLong(long val)
    Create a fully-defined value from the bits of a long
    Parameters:
      `val` - the value to take
    Returns:
      the constructed masked long

  - ### longValue

    public long longValue()
    Obtain the value as a long, where all undefined bits are treated as `0`
    Returns:
      the value as a long

  - ### getMask

    public long getMask()
    Get the mask as a long

    Positions with a defined bit are `1`; positions with an undefined bit are `0`.

    Returns:
      the mask as a long

  - ### isFullyDefined

    public boolean isFullyDefined()
    True iff there are no undefined bits
    Returns:
      true if fully-defined, false otherwise

  - ### isFullyUndefined

    public boolean isFullyUndefined()
    True iff there are no defined bits
    Returns:
      true if full-undefined, false otherwise

  - ### mask

    public MaskedLong mask(long mask)
    Apply an additional mask to this masked long

    Any `0` bit in `msk` will result in an undefined bit in the result. `1` bits result in a copy of the corresponding bit in the result.

    Parameters:
      `mask` - the mask to apply
    Returns:
      the result.

  - ### signExtend

    public MaskedLong signExtend()
    Sign extend the masked value, according to its mask, to a full long

    The leftmost defined bit is taken as the sign bit, and extended to the left.

    Returns:
      the sign-extended masked long

  - ### zeroExtend

    public MaskedLong zeroExtend()
    Zero extend the masked value, according to its mask, to a full long

    All bits to the left of the leftmost defined bit are set to 0.

    Returns:
      the zero-extended masked long

  - ### unknownExtend

    public MaskedLong unknownExtend(int n)
    Mask out all but the lowest `n` bits of the value
    Parameters:
      `n` - the number of bits to take (right-to-left)
    Returns:
      the unknown-extended masked long

  - ### signExtend

    public MaskedLong signExtend(int n)
    Sign extend the masked value as if of the given size in bits, to a full long
    Parameters:
      `n` - the number of bits to take (right-to-left)
    Returns:
      the sign-extended masked long

  - ### zeroExtend

    public MaskedLong zeroExtend(int n)
    Zero extend the masked value as if of the given size in bits, to a full long
    Parameters:
      `n` - the number of bits to take (right-to-left)
    Returns:
      the zero-extended masked long

  - ### combine

    public MaskedLong combine(MaskedLong that) throws SolverException
    Combine this and another masked long into one, by taking defined bits from either

    If this masked long agrees with the other, then the two are combined. For each bit position in the result, the defined bit from either corresponding position is taken. If neither is defined, then the position is undefined in the result. If both are defined, they must agree.

    Parameters:
      `that` - the other masked long
    Returns:
      the combined masked long
    Throws:
      `SolverException` - if this and the other masked long disagree

  - ### shiftCircular

    public MaskedLong shiftCircular(long n, int size, int dir)
    Shift `size` bits @{code n) positions circularly in a given direction

    The shifted bits are the least significant `size` bits. The remaining bits are unaffected.

    Parameters:
      `n` - the number of positions
      `size` - the number of bits (least significant) to include in the shift
      `dir` - the direction to shift (0 for left, 1 for right)
    Returns:
      the result

  - ### shiftCircular

    public MaskedLong shiftCircular(MaskedLong n, int size, int dir)
    Shift `size` bits @{code n) positions circularly in a given direction

    The shifted bits are the least significant `size` bits. The remaining bits are unaffected.

    Parameters:
      `n` - the number of positions
      `size` - the number of bits (least significant) to include in the shift
      `dir` - the direction to shift (0 for left, 1 for right)
    Returns:
      the result

  - ### shiftLeft

    public MaskedLong shiftLeft(long n)
    Shift the bits @{code n} positions left

    This implements both a signed and unsigned shift.

    Parameters:
      `n` - the number of positions.
    Returns:
      the result.

  - ### shiftLeft

    public MaskedLong shiftLeft(MaskedLong n)
    Shift the bits `n` positions left

    This implements both a signed and unsigned shift.

    Parameters:
      `n` - the number of positions.
    Returns:
      the result.

  - ### invShiftLeft

    public MaskedLong invShiftLeft(long n) throws SolverException
    Invert a left shift of `n` positions, that is shift right

    This is different from a normal shift right, in that it inserts unknowns at the left. The normal right shift inserts zeros or sign bits. Additionally, if any ones would fall off the right, the inversion is undefined.

    Parameters:
      `n` - the number of positions
    Returns:
      the result
    Throws:
      `SolverException` - if the inversion is undefined

  - ### invShiftLeft

    public MaskedLong invShiftLeft(MaskedLong n) throws SolverException
    Invert a left shift of `n` positions, that is shift right

    This is different from a normal shift right, in that it inserts unknowns at the left. The normal right shift inserts zeros or sign bits. Additionally, if any ones would fall off the right, the inversion is undefined.

    Parameters:
      `n` - the number of positions
    Returns:
      the result
    Throws:
      `SolverException` - if the inversion is undefined

  - ### shiftRight

    public MaskedLong shiftRight(long n)
    Shift the bits arithmetically `n` positions right

    This implements a signed shift.

    Parameters:
      `n` - the number of positions.
    Returns:
      the result.

  - ### shiftRight

    public MaskedLong shiftRight(MaskedLong n)
    Shift the bits arithmetically `n` positions right

    This implements a signed shift.

    Parameters:
      `n` - the number of positions.
    Returns:
      the result.

  - ### invShiftRight

    public MaskedLong invShiftRight(long n) throws SolverException
    Invert an arithmetic right shift of `n` positions, that is shift left

    This is different from a normal shift left, in that it inserts unknowns at the right. The normal left shift inserts zeros. Additionally, all bits that fall off the left must match the resulting sign bit, or else the inversion is undefined.

    Parameters:
      `n` - the number of positions
    Returns:
      the result
    Throws:
      `SolverException` - if the inversion is undefined

  - ### invShiftRight

    public MaskedLong invShiftRight(MaskedLong n) throws SolverException
    Invert an arithmetic right shift of `n` positions, that is shift left

    This is different from a normal shift left, in that it inserts unknowns at the right. The normal left shift inserts zeros. Additionally, all bits that fall off the left must match the resulting sign bit, or else the inversion is undefined.

    Parameters:
      `n` - the number of positions
    Returns:
      the result
    Throws:
      `SolverException` - if the inversion is undefined

  - ### shiftRightLogical

    public MaskedLong shiftRightLogical(long n)
    Shift the bits logically `n` positions right

    This implements an unsigned shift.

    Parameters:
      `n` - the number of positions.
    Returns:
      the result.

  - ### shiftRightLogical

    public MaskedLong shiftRightLogical(MaskedLong n)
    Shift the bits logically `n` positions right

    This implements an unsigned shift.

    Parameters:
      `n` - the number of positions.
    Returns:
      the result.

  - ### shiftRightPositional

    public MaskedLong shiftRightPositional(long n)
    Shift the bits positionally `n` positions right

    This fills the left with unknown bits

    Parameters:
      `n` -
    Returns:

  - ### invShiftRightLogical

    public MaskedLong invShiftRightLogical(long n) throws SolverException
    Invert a logical right shift of `n` positions, that is shift left

    This is different from a normal shift left, in that it inserts unknowns at the right. The normal left shift inserts zeros. Additionally, if any ones would fall off the left, the inversion is undefined.

    Parameters:
      `n` - the number of positions
    Returns:
      the result
    Throws:
      `SolverException` - if the inversion is undefined

  - ### invShiftRightLogical

    public MaskedLong invShiftRightLogical(MaskedLong n) throws SolverException
    Invert a logical right shift of `n` positions, that is shift left

    This is different from a normal shift left, in that it inserts unknowns at the right. The normal left shift inserts zeros. Additionally, if any ones would fall off the left, the inversion is undefined.

    Parameters:
      `n` - the number of positions
    Returns:
      the result
    Throws:
      `SolverException` - if the inversion is undefined

  - ### byteSwap

    public MaskedLong byteSwap(int n)
    Reverse the least significant `n` bytes

    This interprets the bits as an `n`-byte value and changes the endianness. Any bits outside of the interpretation are truncated, i.e., become unknown.

    Parameters:
      `n` - the size, in bytes, of the interpreted value.
    Returns:
      the result.

  - ### and

    public MaskedLong and(MaskedLong that)
    Compute the bitwise AND of this and another masked long

    To handle unknown bits, the result is derived from the following truth table:

           0 x 1 <= A (this)
         0 0 0 0
         x 0 x x
         1 0 x 1
         ^
         B (that)

    Parameters:
      `that` - the other masked long (`B`).
    Returns:
      the result.

  - ### invAnd

    public MaskedLong invAnd(MaskedLong that) throws SolverException
    Solves the expression `A & B = C, for B, given C and A`

    To handle unknown bits, the solution is derived from the following truth table, where `*` indicates no solution:

           0 x 1 <= A (that)
         0 x x 0
         x x x x
         1 * 1 1
         ^
         B (this)

    Parameters:
      `that` - the other masked long (`B`).
    Returns:
      the result.
    Throws:
      `SolverException` - if no solution exists.

  - ### or

    public MaskedLong or(MaskedLong that)
    Compute the bitwise OR of this and another masked long

    To handle unknown bits, the result is derived from the following truth table:

           0 x 1 <= A (this)
         0 0 x 1
         x x x 1
         1 1 1 1
         ^
         B (that)

    Parameters:
      `that` - the other masked long (`B`).
    Returns:
      the result.

  - ### invOr

    public MaskedLong invOr(MaskedLong that) throws SolverException
    Solves the expression A | B = C, for B, given C and A

    To handle unknown bits, the solution is derived from the following truth table, where `*` indicates no solution:

           0 x 1 <= A (that)
         0 0 0 *
         x x x x
         1 1 x x
         ^
         B (this)

    Parameters:
      `that` - the other masked long (`B`).
    Returns:
      the result.
    Throws:
      `SolverException` - if not solution exists.

  - ### xor

    public MaskedLong xor(MaskedLong that)
    Compute the bitwise XOR of this and another masked long

    To handle unknown bits, the result is derived from the following truth table:

           0 x 1 <= A (this)
         0 0 x 1
         x x x x
         1 1 x 0
         ^
         B (that)

    Parameters:
      `that` - the other masked long (`B`).
    Returns:
      the result.

  - ### negate

    public MaskedLong negate()
    Negate the value
    Returns:
      the result.

  - ### not

    public MaskedLong not()
    Compute the bitwise NOT

    To handle unknown bits, the result is derived from the following truth table:

         0 x 1 <= A (this)
         1 x 0

    Returns:
      the result.

  - ### add

    public MaskedLong add(MaskedLong that)
    Compute the arithmetic sum of this and another masked long
    Parameters:
      `that` - the other masked long.
    Returns:
      the result.

  - ### subtract

    public MaskedLong subtract(MaskedLong that)
    Compute the arithmetic difference: this masked long minus another
    Parameters:
      `that` - the other masked long.
    Returns:
      the result.

  - ### multiply

    public MaskedLong multiply(MaskedLong that)
    Compute the arithmetic product of this and another masked long
    Parameters:
      `that` - the other masked long.
    Returns:
      the result.

  - ### divideSigned

    public MaskedLong divideSigned(MaskedLong that)

  - ### divideUnsigned

    public MaskedLong divideUnsigned(MaskedLong that)
    Compute the unsigned arithmetic quotient: this masked long divided by another
    Parameters:
      `that` - the other masked long.
    Returns:
      the result.

  - ### invMultiplyUnsigned

    public MaskedLong invMultiplyUnsigned(MaskedLong that) throws SolverException
    Compute the arithmetic quotient as a solution to unsigned multiplication

    This is slightly different than `divideUnsigned(MaskedLong)` in its treatment of unknowns.

    Parameters:
      `that` - the known factor
    Returns:
      a solution to that*x == this, if possible
    Throws:
      `SolverException`

  - ### agrees

    public boolean agrees(MaskedLong that)
    Checks if this and another masked long agree

    Two masked longs agree iff their corresponding defined bit positions are equal. Where either or both positions are undefined, no check is applied. In the case that both masked longs are fully-defined, this is the same as an equality check on the values.

    Parameters:
      `that` - the other masked long.
    Returns:
      true if this and that agree.

  - ### agrees

    public boolean agrees(long that)
    Checks if this and a long agree

    The masked long agrees with the given long iff the masked long's defined bit positions agree with the corresponding bit positions in the given long. Where there are undefined bits, no check is applied. In the case that the masked long is fully-defined, this is the same as an equality check on the value.

    Parameters:
      `that` - the long
    Returns:
      true if this and that agree.

  - ### agrees

    public boolean agrees(Object that)
    Check if this and another object agree
    Parameters:
      `that` - a `MaskedLong` or `Long` to check.
    Returns:
      true if this and that agree.
    See Also:
      - `agrees(MaskedLong)`
      - `agrees(long)`

  - ### isInRange

    public boolean isInRange(long max, boolean signed)
    Check if the masked value falls within a given range

    The range is defined by a maximum and a signedness. The maximum must be one less than a positive power of 2. In other words, it defines a maximum number of bits, including the sign bit if applicable.

    The defined bits of this masked long are then checked to fall in the given range. The effective value is derived by sign/zero extending the value according to its mask. In general, if any `1` bits exist outside of the given max, the value is rejected, unless that `1` is purely a result of signedness.

    Parameters:
      `max` - the maximum value, taken as an unsigned long.
      `signed` - true to interpret the masked value as signed.
    Returns:
      true if the masked value "fits" into the given range.

  - ### compareTo

    public int compareTo(MaskedLong that)
    "Compare" two masked longs

    This is not meant to reflect a numerical comparison. Rather, this is just to impose an ordering for the sake of storing these in sorted collections.

    Specified by:
      `compareTo` in interface `Comparable<MaskedLong>`

  - ### equals

    public boolean equals(Object other)
    Check for equality

    This will only return true if the other object is a masked long, even if this one is fully-defined, and the value is equal to a given long (or `Long`). The other masked long must have the same mask and value to be considered equal. For other sorts of "equality" checks, see `agrees(Object)` and friends.

    Overrides:
      `equals` in class `Object`

  - ### hashCode

    public int hashCode()
    Overrides:
      `hashCode` in class `Object`

  - ### toString

    public String toString()
    Overrides:
      `toString` in class `Object`

  - ### signExtend

    protected static long signExtend(long val, int bits)
    Sign extend a number of the given size in bits, to a full long
    Parameters:
      `val` - the value to extend
      `bits` - the number of bits to take (right-to-left)
    Returns:
      the sign-extended value as a long

  - ### zeroExtend

    protected static long zeroExtend(long val, int bits)
    Zero extend a number of the given size in bits, to a full long
    Parameters:
      `val` - the value to extend
      `bits` - the number of bits to take (right-to-left)
    Returns:
      the zero-extended value as a long

  - ### fillMask

    public MaskedLong fillMask()
    Set all undefined bits to 0
    Returns:
      the result