From 0b49807170b8b73c0a1b9b851f53c6c1fd28e16f Mon Sep 17 00:00:00 2001 From: Michael Nolan Date: Mon, 30 Mar 2020 19:35:45 -0400 Subject: [PATCH] Add ROTL32 and ROTL64 --- src/soc/decoder/helpers.py | 66 +++++++++++++++++++++++++++----------- 1 file changed, 48 insertions(+), 18 deletions(-) diff --git a/src/soc/decoder/helpers.py b/src/soc/decoder/helpers.py index a3fbd1db..db17c5bc 100644 --- a/src/soc/decoder/helpers.py +++ b/src/soc/decoder/helpers.py @@ -6,12 +6,18 @@ def exts(value, bits): def EXTS64(value): return exts(value, 64) & ((1<<64)-1) +def rotl(value, bits, wordlen): + mask = (1 << wordlen) - 1 + bits = bits & (wordlen - 1) + return ((value << bits) | (value >> (wordlen-bits))) & mask + def ROTL64(value, bits): - mask = (1 << 64) - 1 - bits = bits & 63 - return ((value << bits) | (value >> (64-bits))) & mask + return rotl(value, bits, 64) + +def ROTL32(value, bits): + return rotl(value, bits, 32) -def mask(x, y): +def MASK(x, y): if x < y: x = 64-x y = 63-y @@ -26,21 +32,45 @@ def mask(x, y): class HelperTests(unittest.TestCase): - def test_mask(self): + def test_MASK(self): # Verified using rlwinm, rldicl, rldicr in qemu - # rlwinm reg, 0, 5, 15 - self.assertHex(mask(5+32, 15+32), 0x7ff0000) - # rlwinm reg, 0, 15, 5 - self.assertHex(mask(15+32, 5+32), 0xfffffffffc01ffff) - self.assertHex(mask(30+32, 2+32), 0xffffffffe0000003) - # rldicl reg, 0, 37 - self.assertHex(mask(37, 63), 0x7ffffff) - self.assertHex(mask(10, 63), 0x3fffffffffffff) - self.assertHex(mask(58, 63), 0x3f) - # rldicr reg, 0, 37 - self.assertHex(mask(0, 37), 0xfffffffffc000000) - self.assertHex(mask(0, 10), 0xffe0000000000000) - self.assertHex(mask(0, 58), 0xffffffffffffffe0) + # li 1, -1 + # rlwinm reg, 1, 0, 5, 15 + self.assertHex(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) + # rldicl reg, 1, 0, 37 + self.assertHex(MASK(37, 63), 0x7ffffff) + self.assertHex(MASK(10, 63), 0x3fffffffffffff) + self.assertHex(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) + + def test_ROTL64(self): + # r1 = 0xdeadbeef12345678 + value = 0xdeadbeef12345678 + + # rldicl reg, 1, 10, 0 + self.assertHex(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) + + def test_ROTL32(self): + # r1 = 0xdeadbeef + value = 0xdeadbeef + + # rlwinm reg, 1, 10, 0, 31 + self.assertHex(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) + def assertHex(self, a, b): msg = "{:x} != {:x}".format(a, b) return self.assertEqual(a, b, msg) -- 2.30.2