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
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
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)
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
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)
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)
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
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