import unittest
+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
+
+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)
+
+def EXTS(value):
+ """ extends sign bit out from current MSB to all 256 bits
+ """
+ assert isinstance(value, SelectableInt)
+ return SelectableInt(exts(value.value, value.bits) & ((1 << 256)-1), 256)
+
+
def EXTS64(value):
- return exts(value, 32) & ((1<<64)-1)
+ """ extends sign bit out from current MSB to 64 bits
+ """
+ assert isinstance(value, SelectableInt)
+ return SelectableInt(exts(value.value, value.bits) & ((1 << 64)-1), 64)
+
+# signed version of MUL
+def MULS(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):
- return value & ((1<<32)-1)
+ if isinstance(value, SelectableInt):
+ value = value.value
+ return SelectableInt(value & ((1 << 32)-1), 64)
+
def rotl(value, bits, wordlen):
+ if isinstance(bits, SelectableInt):
+ bits = bits.value
mask = (1 << wordlen) - 1
bits = bits & (wordlen - 1)
return ((value << bits) | (value >> (wordlen-bits))) & mask
+
def ROTL64(value, bits):
return rotl(value, bits, 64)
+
def ROTL32(value, bits):
- return rotl(value, bits, 32)
+ if isinstance(value, SelectableInt):
+ value = SelectableInt(value.value, 64)
+ return rotl(value | (value << 32), bits, 64)
+
def MASK(x, y):
+ if isinstance(x, SelectableInt):
+ x = x.value
+ if isinstance(y, SelectableInt):
+ y = y.value
if x < y:
x = 64-x
y = 63-y
- mask_a = ((1<<x) - 1) & ((1<<64) - 1)
- mask_b = ((1<<y) - 1) & ((1<<64) - 1)
+ mask_a = ((1 << x) - 1) & ((1 << 64) - 1)
+ mask_b = ((1 << y) - 1) & ((1 << 64) - 1)
+ elif x == y:
+ return 1 << (63-x)
else:
x = 64-x
y = 63-y
- mask_a = ((1<<x) - 1) & ((1<<64) - 1)
- mask_b = (~((1<<y) - 1)) & ((1<<64) - 1)
+ mask_a = ((1 << x) - 1) & ((1 << 64) - 1)
+ mask_b = (~((1 << y) - 1)) & ((1 << 64) - 1)
return mask_a ^ mask_b
+def ne(a, b):
+ return onebit(a != b)
+
+
+def eq(a, b):
+ return onebit(a == b)
+
+
+def gt(a, b):
+ return onebit(a > b)
+
+
+def ge(a, b):
+ return onebit(a >= b)
+
+
+def lt(a, b):
+ return onebit(a < b)
+
+
+def le(a, b):
+ return onebit(a <= b)
+
+
+def length(a):
+ return len(a)
+
+# 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
self.assertHex(MASK(0, 10), 0xffe0000000000000)
self.assertHex(MASK(0, 58), 0xffffffffffffffe0)
+ # li 2, 5
+ # slw 1, 1, 2
+ self.assertHex(MASK(32, 63-5), 0xffffffe0)
+
+ self.assertHex(MASK(32, 33), 0xc0000000)
+ self.assertHex(MASK(32, 32), 0x80000000)
+ self.assertHex(MASK(33, 33), 0x40000000)
+
def test_ROTL64(self):
# r1 = 0xdeadbeef12345678
value = 0xdeadbeef12345678
self.assertHex(ROTL32(value, 30), 0xf7ab6fbb)
def test_EXTS64(self):
- value_a = 0xdeadbeef # r1
- value_b = 0x73123456 # r2
- value_c = 0x80000000 # r3
+ value_a = SelectableInt(0xdeadbeef, 32) # r1
+ value_b = SelectableInt(0x73123456, 32) # r2
+ value_c = SelectableInt(0x80000000, 32) # r3
+ # extswsli reg, 1, 0
self.assertHex(EXTS64(value_a), 0xffffffffdeadbeef)
- self.assertHex(EXTS64(value_b), value_b)
+ # extswsli reg, 2, 0
+ self.assertHex(EXTS64(value_b), SelectableInt(value_b.value, 64))
+ # extswsli reg, 3, 0
self.assertHex(EXTS64(value_c), 0xffffffff80000000)
-
-
def assertHex(self, a, b):
- msg = "{:x} != {:x}".format(a, b)
+ a_val = a
+ if isinstance(a, SelectableInt):
+ a_val = a.value
+ b_val = b
+ if isinstance(b, SelectableInt):
+ b_val = b.value
+ msg = "{:x} != {:x}".format(a_val, b_val)
return self.assertEqual(a, b, msg)
+
if __name__ == '__main__':
+ print(SelectableInt.__bases__)
unittest.main()