return SelectableInt((value << bits) & mask, 64)
-def ROTL64(value, bits):
- return rotl(value, bits, 64)
-
-
-def ROTL32(value, bits):
- if isinstance(bits, SelectableInt):
- bits = bits.value
- if isinstance(value, SelectableInt):
- value = SelectableInt(value.value, 64)
- return rotl(value | (value << 32), bits, 64)
-
-
-def MASK32(x, y):
- if isinstance(x, SelectableInt):
- x = x.value
- if isinstance(y, SelectableInt):
- y = y.value
- return MASK(x+32, y+32)
-
-
-def MASK(x, y, lim=64):
- if isinstance(x, SelectableInt):
- x = x.value
- if isinstance(y, SelectableInt):
- y = y.value
- if x < y:
- x = lim-x
- y = (lim-1)-y
- mask_a = ((1 << x) - 1) & ((1 << lim) - 1)
- mask_b = ((1 << y) - 1) & ((1 << lim) - 1)
- elif x == y:
- return 1 << ((lim-1)-x)
- else:
- x = lim-x
- y = (lim-1)-y
- mask_a = ((1 << x) - 1) & ((1 << lim) - 1)
- mask_b = (~((1 << y) - 1)) & ((1 << lim) - 1)
- return mask_a ^ mask_b
-
-
def ne(a, b):
return onebit(a != b)
return retval
+class ISACallerHelper:
+ def __init__(self, XLEN):
+ self.__XLEN = XLEN
+
+ @property
+ def XLEN(self):
+ return self.__XLEN
+
+ def XLCASTS(self, value):
+ return SelectableInt(exts(value.value, self.XLEN), self.XLEN)
+
+ def XLCASTU(self, value):
+ # SelectableInt already takes care of masking out the bits
+ return SelectableInt(value.value, self.XLEN)
+
+ def EXTSXL(self, value, bits):
+ return SelectableInt(exts(value.value, bits), self.XLEN)
+
+ def DOUBLE2SINGLE(self, FRS):
+ """ DOUBLE2SINGLE has been renamed to FRSP since it is the
+ implementation of the frsp instruction.
+ use SINGLE() or FRSP() instead, or just use struct.pack/unpack
+ """
+ FPSCR = {
+ 'UE': SelectableInt(0, 1),
+ 'OE': SelectableInt(0, 1),
+ 'RN': SelectableInt(0, 2), # round to nearest, ties to even
+ 'XX': SelectableInt(0, 1),
+ }
+ FRT, FPSCR = self.FRSP(FRS, FPSCR)
+ return FRT
+
+ def ROTL32(self, value, bits):
+ if isinstance(bits, SelectableInt):
+ bits = bits.value
+ if isinstance(value, SelectableInt):
+ value = SelectableInt(value.value, self.XLEN)
+ value = value | (value << (self.XLEN//2))
+ value = rotl(value, bits, self.XLEN)
+ return value
+
+ def ROTL64(self, value, bits):
+ return rotl(value, bits, self.XLEN)
+
+ def MASK32(self, x, y):
+ if isinstance(x, SelectableInt):
+ x = x.value
+ if isinstance(y, SelectableInt):
+ y = y.value
+ return self.MASK(x+(self.XLEN//2), y+(self.XLEN//2))
+
+ def MASK(self, x, y, lim=None):
+ if lim is None:
+ lim = self.XLEN
+ if isinstance(x, SelectableInt):
+ x = x.value
+ if isinstance(y, SelectableInt):
+ y = y.value
+ if x < y:
+ x = lim-x
+ y = (lim-1)-y
+ mask_a = ((1 << x) - 1) & ((1 << lim) - 1)
+ mask_b = ((1 << y) - 1) & ((1 << lim) - 1)
+ elif x == y:
+ return 1 << ((lim-1)-x)
+ else:
+ x = lim-x
+ y = (lim-1)-y
+ mask_a = ((1 << x) - 1) & ((1 << lim) - 1)
+ mask_b = (~((1 << y) - 1)) & ((1 << lim) - 1)
+ return mask_a ^ mask_b
+
+ def __getattr__(self, attr):
+ """workaround for getting function out of the global namespace
+ within this module, as a way to get functions being transitioned
+ to Helper classes within ISACaller (and therefore pseudocode)
+ """
+ try:
+ return globals()[attr]
+ except KeyError:
+ raise AttributeError(attr)
+
+
# 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, ISACallerHelper):
+ def __init__(self, *args, **kwargs):
+ ISACallerHelper.__init__(self, 64) # TODO: dynamic (64/32/16/8)
+ unittest.TestCase.__init__(self, *args, **kwargs)
-class HelperTests(unittest.TestCase):
def test_MASK(self):
# Verified using rlwinm, rldicl, rldicr in qemu
# li 1, -1
# rlwinm reg, 1, 0, 5, 15
- self.assertHex(MASK(5+32, 15+32), 0x7ff0000)
+ self.assertHex(self.MASK(5+32, 15+32), 0x7ff0000)
# rlwinm reg, 1, 0, 15, 5
- self.assertHex(MASK(15+32, 5+32), 0xfffffffffc01ffff)
- self.assertHex(MASK(30+32, 2+32), 0xffffffffe0000003)
+ self.assertHex(self.MASK(15+32, 5+32), 0xfffffffffc01ffff)
+ self.assertHex(self.MASK(30+32, 2+32), 0xffffffffe0000003)
# rldicl reg, 1, 0, 37
- self.assertHex(MASK(37, 63), 0x7ffffff)
- self.assertHex(MASK(10, 63), 0x3fffffffffffff)
- self.assertHex(MASK(58, 63), 0x3f)
+ self.assertHex(self.MASK(37, 63), 0x7ffffff)
+ self.assertHex(self.MASK(10, 63), 0x3fffffffffffff)
+ self.assertHex(self.MASK(58, 63), 0x3f)
# rldicr reg, 1, 0, 37
- self.assertHex(MASK(0, 37), 0xfffffffffc000000)
- self.assertHex(MASK(0, 10), 0xffe0000000000000)
- self.assertHex(MASK(0, 58), 0xffffffffffffffe0)
+ self.assertHex(self.MASK(0, 37), 0xfffffffffc000000)
+ self.assertHex(self.MASK(0, 10), 0xffe0000000000000)
+ self.assertHex(self.MASK(0, 58), 0xffffffffffffffe0)
# li 2, 5
# slw 1, 1, 2
- self.assertHex(MASK(32, 63-5), 0xffffffe0)
+ self.assertHex(self.MASK(32, 63-5), 0xffffffe0)
- self.assertHex(MASK(32, 33), 0xc0000000)
- self.assertHex(MASK(32, 32), 0x80000000)
- self.assertHex(MASK(33, 33), 0x40000000)
+ self.assertHex(self.MASK(32, 33), 0xc0000000)
+ self.assertHex(self.MASK(32, 32), 0x80000000)
+ self.assertHex(self.MASK(33, 33), 0x40000000)
def test_ROTL64(self):
# r1 = 0xdeadbeef12345678
value = 0xdeadbeef12345678
# rldicl reg, 1, 10, 0
- self.assertHex(ROTL64(value, 10), 0xb6fbbc48d159e37a)
+ self.assertHex(self.ROTL64(value, 10), 0xb6fbbc48d159e37a)
# rldicl reg, 1, 35, 0
- self.assertHex(ROTL64(value, 35), 0x91a2b3c6f56df778)
- self.assertHex(ROTL64(value, 58), 0xe37ab6fbbc48d159)
- self.assertHex(ROTL64(value, 22), 0xbbc48d159e37ab6f)
+ self.assertHex(self.ROTL64(value, 35), 0x91a2b3c6f56df778)
+ self.assertHex(self.ROTL64(value, 58), 0xe37ab6fbbc48d159)
+ self.assertHex(self.ROTL64(value, 22), 0xbbc48d159e37ab6f)
def test_ROTL32(self):
# r1 = 0xdeadbeef
- value = 0xdeadbeef
+ value = SelectableInt(0xdeadbeef, self.XLEN)
# rlwinm reg, 1, 10, 0, 31
- self.assertHex(ROTL32(value, 10), 0xb6fbbf7a)
+ self.assertHex(self.ROTL32(value, 10), 0xb6fbbf7a)
# rlwinm reg, 1, 17, 0, 31
- self.assertHex(ROTL32(value, 17), 0x7ddfbd5b)
- self.assertHex(ROTL32(value, 25), 0xdfbd5b7d)
- self.assertHex(ROTL32(value, 30), 0xf7ab6fbb)
+ self.assertHex(self.ROTL32(value, 17), 0x7ddfbd5b)
+ self.assertHex(self.ROTL32(value, 25), 0xdfbd5b7d)
+ self.assertHex(self.ROTL32(value, 30), 0xf7ab6fbb)
def test_EXTS64(self):
value_a = SelectableInt(0xdeadbeef, 32) # r1
value_c = SelectableInt(0x80000000, 32) # r3
# extswsli reg, 1, 0
- self.assertHex(EXTS64(value_a), 0xffffffffdeadbeef)
+ self.assertHex(self.EXTS64(value_a), 0xffffffffdeadbeef)
# extswsli reg, 2, 0
- self.assertHex(EXTS64(value_b), SelectableInt(value_b.value, 64))
+ self.assertHex(self.EXTS64(value_b), SelectableInt(value_b.value, 64))
# extswsli reg, 3, 0
- self.assertHex(EXTS64(value_c), 0xffffffff80000000)
+ self.assertHex(self.EXTS64(value_c), 0xffffffff80000000)
def test_FPADD32(self):
value_a = SelectableInt(0x4014000000000000, 64) # 5.0
return self.assertEqual(a, b, msg)
-class ISACallerHelper:
- def __init__(self, XLEN):
- self.__XLEN = XLEN
-
- @property
- def XLEN(self):
- return self.__XLEN
-
- def XLCASTS(self, value):
- return SelectableInt(exts(value.value, self.XLEN), self.XLEN)
-
- def XLCASTU(self, value):
- # SelectableInt already takes care of masking out the bits
- return SelectableInt(value.value, self.XLEN)
-
- def EXTSXL(self, value, bits):
- return SelectableInt(exts(value.value, bits), self.XLEN)
-
- def DOUBLE2SINGLE(self, FRS):
- """ DOUBLE2SINGLE has been renamed to FRSP since it is the
- implementation of the frsp instruction.
- use SINGLE() or FRSP() instead, or just use struct.pack/unpack
- """
- FPSCR = {
- 'UE': SelectableInt(0, 1),
- 'OE': SelectableInt(0, 1),
- 'RN': SelectableInt(0, 2), # round to nearest, ties to even
- 'XX': SelectableInt(0, 1),
- }
- FRT, FPSCR = self.FRSP(FRS, FPSCR)
- return FRT
-
- def __getattr__(self, attr):
- try:
- return globals()[attr]
- except KeyError:
- raise AttributeError(attr)
-
if __name__ == '__main__':
log(SelectableInt.__bases__)