Add ROTL32 and ROTL64
authorMichael Nolan <mtnolan2640@gmail.com>
Mon, 30 Mar 2020 23:35:45 +0000 (19:35 -0400)
committerMichael Nolan <mtnolan2640@gmail.com>
Mon, 30 Mar 2020 23:35:45 +0000 (19:35 -0400)
src/soc/decoder/helpers.py

index a3fbd1dbbb29571fbce7cb5dee66307e1bc67764..db17c5bc9172a39d45f091f9507c0dceae72d1fa 100644 (file)
@@ -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)