radix: reading first page table entry
[soc.git] / src / soc / decoder / helpers.py
index d920b920f89614c07809aca3194e326f15811f98..6f63cc3d363596c72290123719cacdc8c5d94862 100644 (file)
@@ -1,12 +1,22 @@
 import unittest
-from soc.decoder.selectable_int import SelectableInt
-from nmutil.divmod import trunc_div, trunc_rem
+from soc.decoder.selectable_int import SelectableInt, onebit
+from nmutil.divmod import trunc_divs, trunc_rems
+from operator import floordiv, mod
+from soc.decoder.selectable_int import selectltu as ltu
+from soc.decoder.selectable_int import selectgtu as gtu
+from soc.decoder.selectable_int import check_extsign
+
+trunc_div = floordiv
+trunc_rem = mod
+DIVS = trunc_divs
+MODS = trunc_rems
 
 """
 Links:
 * https://bugs.libre-soc.org/show_bug.cgi?id=324 - add trunc_div and trunc_rem
 """
 
+
 def exts(value, bits):
     sign = 1 << (bits - 1)
     return (value & (sign - 1)) - (value & sign)
@@ -18,6 +28,7 @@ def EXTS(value):
     assert isinstance(value, SelectableInt)
     return SelectableInt(exts(value.value, value.bits) & ((1 << 256)-1), 256)
 
+
 def EXTS64(value):
     """ extends sign bit out from current MSB to 64 bits
     """
@@ -25,11 +36,32 @@ def EXTS64(value):
     return SelectableInt(exts(value.value, value.bits) & ((1 << 64)-1), 64)
 
 
+def EXTS128(value):
+    """ extends sign bit out from current MSB to 128 bits
+    """
+    assert isinstance(value, SelectableInt)
+    return SelectableInt(exts(value.value, value.bits) & ((1 << 128)-1), 128)
+
+
+# signed version of MUL
+def MULS(a, b):
+    if isinstance(b, int):
+        b = SelectableInt(b, self.bits)
+    b = check_extsign(a, b)
+    a_s = a.value & (1 << (a.bits-1)) != 0
+    b_s = b.value & (1 << (b.bits-1)) != 0
+    result = abs(a) * abs(b)
+    print("MULS", result, a_s, b_s)
+    if a_s == b_s:
+        return result
+    return -result
+
+
 # XXX should this explicitly extend from 32 to 64?
 def EXTZ64(value):
     if isinstance(value, SelectableInt):
         value = value.value
-    return SelectableInt(value & ((1<<32)-1), 64)
+    return SelectableInt(value & ((1 << 32)-1), 64)
 
 
 def rotl(value, bits, wordlen):
@@ -69,33 +101,51 @@ def MASK(x, y):
         mask_b = (~((1 << y) - 1)) & ((1 << 64) - 1)
     return mask_a ^ mask_b
 
+
 def ne(a, b):
-    return SelectableInt((a != b), bits=1)
+    return onebit(a != b)
+
 
 def eq(a, b):
-    return SelectableInt((a == b), bits=1)
+    return onebit(a == b)
+
 
 def gt(a, b):
-    return SelectableInt((a > b), bits=1)
+    return onebit(a > b)
+
 
 def ge(a, b):
-    return SelectableInt((a >= b), bits=1)
+    return onebit(a >= b)
+
 
 def lt(a, b):
-    return SelectableInt((a < b), bits=1)
+    return onebit(a < b)
+
 
 def le(a, b):
-    return SelectableInt((a <= b), bits=1)
+    return onebit(a <= b)
+
 
 def length(a):
     return len(a)
 
+
+def undefined(v):
+    """ function that, for Power spec purposes, returns undefined bits of
+        the same shape as the input bits.  however, for purposes of matching
+        POWER9's behavior returns the input bits unchanged.  this effectively
+        "marks" (tags) locations in the v3.0B spec that need to be submitted
+        for clarification.
+    """
+    return v
+
 # For these tests I tried to find power instructions that would let me
 # isolate each of these helper operations. So for instance, when I was
 # testing the MASK() function, I chose rlwinm and rldicl because if I
 # set the shift equal to 0 and passed in a value of all ones, the
 # result I got would be exactly the same as the output of MASK()
 
+
 class HelperTests(unittest.TestCase):
     def test_MASK(self):
         # Verified using rlwinm, rldicl, rldicr in qemu
@@ -168,5 +218,5 @@ class HelperTests(unittest.TestCase):
 
 
 if __name__ == '__main__':
-    print (SelectableInt.__bases__)
+    print(SelectableInt.__bases__)
     unittest.main()