X-Git-Url: https://git.libre-soc.org/?a=blobdiff_plain;f=src%2Fopenpower%2Fdecoder%2Fselectable_int.py;h=1e7458ee9f8e0de4c68ebbe7bd0580b80c92f3c9;hb=b0f8c99ebeb16d0507d9ea7ef27b2c90a0ba3dd2;hp=2afe50e67d5887e81ac8bde6307aa4a34d510c88;hpb=f01e569f6061be6677dd4874812d2a39bd45fe2d;p=openpower-isa.git diff --git a/src/openpower/decoder/selectable_int.py b/src/openpower/decoder/selectable_int.py index 2afe50e6..1e7458ee 100644 --- a/src/openpower/decoder/selectable_int.py +++ b/src/openpower/decoder/selectable_int.py @@ -1,8 +1,11 @@ import unittest +import struct from copy import copy +import functools from openpower.decoder.power_fields import BitRange from operator import (add, sub, mul, floordiv, truediv, mod, or_, and_, xor, neg, inv, lshift, rshift) +from openpower.util import log def check_extsign(a, b): @@ -21,7 +24,7 @@ class FieldSelectableInt: def __init__(self, si, br): self.si = si # target selectable int - if isinstance(br, list) or isinstance(br, tuple): + if isinstance(br, (list, tuple, range)): _br = BitRange() for i, v in enumerate(br): _br[i] = v @@ -29,7 +32,13 @@ class FieldSelectableInt: self.br = br # map of indices. def eq(self, b): - if isinstance(b, SelectableInt): + if isinstance(b, int): + # convert integer to same SelectableInt of same bitlength as range + blen = len(self.br) + b = SelectableInt(b, blen) + for i in range(b.bits): + self[i] = b[i] + elif isinstance(b, SelectableInt): for i in range(b.bits): self[i] = b[i] else: @@ -47,7 +56,7 @@ class FieldSelectableInt: return self.merge(vi) def __getitem__(self, key): - print("getitem", key, self.br) + log("getitem", key, self.br) if isinstance(key, SelectableInt): key = key.value if isinstance(key, int): @@ -112,14 +121,14 @@ class FieldSelectableInt: return fi def __repr__(self): - return "FieldSelectableInt(si=%s, br=%s)" % (self.si, self.br) + return f"{self.__class__.__name__}(si={self.si}, br={self.br})" def asint(self, msb0=False): res = 0 brlen = len(self.br) for i, key in self.br.items(): bit = self.si[key].value - #print("asint", i, key, bit) + #log("asint", i, key, bit) res |= bit << ((brlen-i-1) if msb0 else i) return res @@ -134,7 +143,7 @@ class FieldSelectableIntTestCase(unittest.TestCase): br[2] = 3 fs = FieldSelectableInt(a, br) c = fs + b - print(c) + log(c) #self.assertEqual(c.value, a.value + b.value) def test_select(self): @@ -162,6 +171,7 @@ class FieldSelectableIntTestCase(unittest.TestCase): fs[0:2] = 0b10 self.assertEqual(fs.get_range(), 0b1011) + class SelectableInt: """SelectableInt - a class that behaves exactly like python int @@ -174,8 +184,9 @@ class SelectableInt: including negative start/end points. """ - def __init__(self, value, bits): + def __init__(self, value, bits=None): if isinstance(value, SelectableInt): + bits = value.bits value = value.value mask = (1 << bits) - 1 self.value = value & mask @@ -187,13 +198,13 @@ class SelectableInt: self.bits = b.bits def to_signed_int(self): - print ("to signed?", self.value & (1<<(self.bits-1)), self.value) + log ("to signed?", self.value & (1<<(self.bits-1)), self.value) if self.value & (1<<(self.bits-1)) != 0: # negative res = self.value - (1<> key) & 1 - print("getitem", key, self.bits, hex(self.value), value) + log("getitem", key, self.bits, hex(self.value), value) return SelectableInt(value, 1) elif isinstance(key, slice): assert key.step is None or key.step == 1 @@ -299,23 +310,24 @@ class SelectableInt: start = self.bits - key.stop bits = stop - start - #print ("__getitem__ slice num bits", start, stop, bits) + #log ("__getitem__ slice num bits", start, stop, bits) mask = (1 << bits) - 1 value = (self.value >> start) & mask - print("getitem", stop, start, self.bits, hex(self.value), value) + log("getitem", stop, start, self.bits, hex(self.value), value) return SelectableInt(value, bits) def __setitem__(self, key, value): if isinstance(key, SelectableInt): key = key.value - print("setitem", key, self.bits, hex(self.value)) if isinstance(key, int): - assert key < self.bits - assert key >= 0 - key = self.bits - (key + 1) if isinstance(value, SelectableInt): assert value.bits == 1 value = value.value + log("setitem", key, self.bits, hex(self.value), hex(value)) + + assert key < self.bits + assert key >= 0 + key = self.bits - (key + 1) value = value << key mask = 1 << key @@ -324,16 +336,18 @@ class SelectableInt: assert key.step is None or key.step == 1 assert key.start < key.stop assert key.start >= 0 - assert key.stop <= self.bits + assert key.stop <= self.bits, \ + "key stop %d bits %d" % (key.stop, self.bits) stop = self.bits - key.start start = self.bits - key.stop bits = stop - start - #print ("__setitem__ slice num bits", bits) + #log ("__setitem__ slice num bits", bits) if isinstance(value, SelectableInt): assert value.bits == bits, "%d into %d" % (value.bits, bits) value = value.value + log("setitem", key, self.bits, hex(self.value), hex(value)) mask = ((1 << bits) - 1) << start value = value << start self.value = (self.value & ~mask) | (value & mask) @@ -372,7 +386,7 @@ class SelectableInt: assert False def __lt__(self, other): - print ("SelectableInt lt", self, other) + log ("SelectableInt lt", self, other) if isinstance(other, FieldSelectableInt): other = other.get_range() if isinstance(other, SelectableInt): @@ -382,19 +396,19 @@ class SelectableInt: if isinstance(other, int): a = self.to_signed_int() res = onebit(a < other) - print (" a < b", a, other, res) + log (" a < b", a, other, res) return res assert False def __eq__(self, other): - print("__eq__", self, other) + log("__eq__", self, other) if isinstance(other, FieldSelectableInt): other = other.get_range() if isinstance(other, SelectableInt): other = check_extsign(self, other) assert other.bits == self.bits other = other.value - print (" eq", other, self.value, other == self.value) + log (" eq", other, self.value, other == self.value) if isinstance(other, int): return onebit(other == self.value) assert False @@ -407,8 +421,8 @@ class SelectableInt: return self.value != 0 def __repr__(self): - return "SelectableInt(value=0x{:x}, bits={})".format(self.value, - self.bits) + value = f"value=0x{self.value:x}, bits={self.bits}" + return f"{self.__class__.__name__}({value})" def __len__(self): return self.bits @@ -416,6 +430,64 @@ class SelectableInt: def asint(self): return self.value + def __float__(self): + """convert to double-precision float. TODO, properly convert + rather than a hack-job: must actually support Power IEEE754 FP + """ + assert self.bits == 64 # must be 64-bit + data = self.value.to_bytes(8, byteorder='little') + return struct.unpack('