Exemple #1
0
    def __lshift__(self, other: Union[int, "Bits3val"]) -> "Bits3val":
        "Operator <<."
        try:
            o = int(other)
        except ValidityError:
            o = None

        v = self.__copy__()
        if o is None:
            v.vld_mask = 0
            v.val = 0
        elif o == 0:
            return v
        else:
            if o < 0:
                raise ValueError("negative shift count")
            t = self._dtype
            m = t.all_mask()
            v.vld_mask <<= o
            v.vld_mask |= mask(o)
            v.vld_mask &= m
            v.val <<= o
            v.val &= m
            if t.signed:
                v.val = to_signed(v.val, t.bit_length())
        return v
Exemple #2
0
 def __invert__(self) -> "Bits3val":
     "Operator ~x."
     v = self.__copy__()
     v.val = ~v.val
     w = v._dtype.bit_length()
     v.val &= mask(w)
     if self._dtype.signed:
         v.val = to_signed(v.val, w)
     return v
Exemple #3
0
 def test_8b_lshift(self, t=int8_t):
     w = t.bit_length()
     for i in range(w + 1):
         if i == w:
             v = 0
         else:
             v = (1 << i) & t.all_mask()
             if t.signed:
                 v = to_signed(v, w)
         self.assertEqual(t.from_py(1) << i, v)
Exemple #4
0
    def cast(self, t: Bits3t) -> "Bits3val":
        """
        C++: static_cast<t>(self)

        :note: no sign extension
        """
        v = self.__copy__()
        v._dtype = t
        m = t.all_mask()
        v.val &= m
        v.vld_mask &= m
        if t.signed:
            v.val = to_signed(v.val, t.bit_length())
        return v
Exemple #5
0
def bitsBitOp__val(self: Bits3val, other: Union[Bits3val, int], evalFn,
                   getVldFn) -> "Bits3val":
    """
    Apply bitwise operator
    """
    if isinstance(other, int):
        other = self._dtype.from_py(other)
    w = self._dtype.bit_length()
    assert w == other._dtype.bit_length(), (self._dtype, other._dtype)
    vld = getVldFn(self, other)
    res = evalFn(self.val, other.val) & vld
    if self._dtype.signed:
        res = to_signed(res, w)

    return self._dtype.from_py(res, vld)
Exemple #6
0
    def __mul__(self, other: Union[int, "Bits3val"]) -> "Bits3val":
        "Operator *."
        # [TODO] resT should be wider
        resT = self._dtype
        other_is_int = isinstance(other, int)
        if other_is_int:
            v = self.val * other
        elif isinstance(other, Bits3val):
            v = self.val * other.val
        else:
            raise TypeError(other)

        v &= resT.all_mask()
        if resT.signed:
            v = to_signed(v, resT.bit_length())

        if self._is_full_valid() and (other_is_int or other._is_full_valid()):
            vld_mask = None
        else:
            vld_mask = 0

        return resT.from_py(v, vld_mask=vld_mask)
Exemple #7
0
    def cast_sign(self, signed) -> "Bits3val":
        """
        Cast signed-unsigned value
        """
        t = self._dtype
        if t.signed == signed:
            return self
        selfSign = t.signed
        v = self.__copy__()
        m = t._all_mask
        _v = v.val

        if selfSign and not signed:
            if _v < 0:
                v.val = m + _v + 1
        elif not selfSign and signed:
            w = t.bit_length()
            v.val = to_signed(_v, w)

        v._dtype = v._dtype.__copy__()
        v._dtype = self._dtype.__copy__()
        v._dtype.signed = signed
        return v
Exemple #8
0
    def _normalize_val_and_mask(self, val, vld_mask):
        if val is None:
            vld = 0
            val = 0
            assert vld_mask is None or vld_mask == 0
        else:
            all_mask = self.all_mask()
            w = self.bit_length()
            if isinstance(val, bytes):
                val = int.from_bytes(val,
                                     byteorder="little",
                                     signed=bool(self.signed))
            elif isinstance(val, str):
                if not (val.startswith("0") and len(val) > 2):
                    raise ValueError(val)

                base = INT_BASES[val[1]]
                try:
                    _val = int(val[2:], base)
                except ValueError:
                    _val = None

                if _val is None:
                    assert vld_mask is None
                    val = val.lower()
                    if base == 10 and "x" in val:
                        raise NotImplementedError()
                    v = 0
                    m = 0
                    bits_per_char = ceil(log2(base))
                    char_mask = mask(bits_per_char)
                    for digit in val[2:]:
                        v <<= bits_per_char
                        m <<= bits_per_char
                        if digit == "x":
                            pass
                        else:
                            m |= char_mask
                            v |= int(digit, base)
                    val = v
                    vld_mask = m
                else:
                    val = _val
            else:
                try:
                    val = int(val)
                except TypeError as e:
                    if isinstance(val, Enum):
                        val = int(val.value)
                    else:
                        raise e

            if vld_mask is None:
                vld = all_mask
            else:
                if vld_mask > all_mask or vld_mask < 0:
                    raise ValueError("Mask in incorrect format", vld_mask)
                vld = vld_mask

            if val < 0:
                if not self.signed:
                    raise ValueError("Negative value for unsigned int")
                _val = to_signed(val & all_mask, w)
                if _val != val:
                    raise ValueError("Too large value", val, _val)
                val = _val
            else:
                if self.signed:
                    msb = 1 << (w - 1)
                    if msb & val:
                        if val > 0:
                            raise ValueError(
                                "Value too large to fit in this type", val)

                if val & all_mask != val:
                    raise ValueError("Not enought bits to represent value",
                                     val, w, val & all_mask)
                val = val & vld
        return val, vld