Add ROTL32 and ROTL64
[soc.git] / src / soc / decoder / helpers.py
1 import unittest
2 def exts(value, bits):
3 sign = 1 << (bits - 1)
4 return (value * (sign - 1)) - (value * sign)
5
6 def EXTS64(value):
7 return exts(value, 64) & ((1<<64)-1)
8
9 def rotl(value, bits, wordlen):
10 mask = (1 << wordlen) - 1
11 bits = bits & (wordlen - 1)
12 return ((value << bits) | (value >> (wordlen-bits))) & mask
13
14 def ROTL64(value, bits):
15 return rotl(value, bits, 64)
16
17 def ROTL32(value, bits):
18 return rotl(value, bits, 32)
19
20 def MASK(x, y):
21 if x < y:
22 x = 64-x
23 y = 63-y
24 mask_a = ((1<<x) - 1) & ((1<<64) - 1)
25 mask_b = ((1<<y) - 1) & ((1<<64) - 1)
26 else:
27 x = 64-x
28 y = 63-y
29 mask_a = ((1<<x) - 1) & ((1<<64) - 1)
30 mask_b = (~((1<<y) - 1)) & ((1<<64) - 1)
31 return mask_a ^ mask_b
32
33
34 class HelperTests(unittest.TestCase):
35 def test_MASK(self):
36 # Verified using rlwinm, rldicl, rldicr in qemu
37 # li 1, -1
38 # rlwinm reg, 1, 0, 5, 15
39 self.assertHex(MASK(5+32, 15+32), 0x7ff0000)
40 # rlwinm reg, 1, 0, 15, 5
41 self.assertHex(MASK(15+32, 5+32), 0xfffffffffc01ffff)
42 self.assertHex(MASK(30+32, 2+32), 0xffffffffe0000003)
43 # rldicl reg, 1, 0, 37
44 self.assertHex(MASK(37, 63), 0x7ffffff)
45 self.assertHex(MASK(10, 63), 0x3fffffffffffff)
46 self.assertHex(MASK(58, 63), 0x3f)
47 # rldicr reg, 1, 0, 37
48 self.assertHex(MASK(0, 37), 0xfffffffffc000000)
49 self.assertHex(MASK(0, 10), 0xffe0000000000000)
50 self.assertHex(MASK(0, 58), 0xffffffffffffffe0)
51
52 def test_ROTL64(self):
53 # r1 = 0xdeadbeef12345678
54 value = 0xdeadbeef12345678
55
56 # rldicl reg, 1, 10, 0
57 self.assertHex(ROTL64(value, 10), 0xb6fbbc48d159e37a)
58 # rldicl reg, 1, 35, 0
59 self.assertHex(ROTL64(value, 35), 0x91a2b3c6f56df778)
60 self.assertHex(ROTL64(value, 58), 0xe37ab6fbbc48d159)
61 self.assertHex(ROTL64(value, 22), 0xbbc48d159e37ab6f)
62
63 def test_ROTL32(self):
64 # r1 = 0xdeadbeef
65 value = 0xdeadbeef
66
67 # rlwinm reg, 1, 10, 0, 31
68 self.assertHex(ROTL32(value, 10), 0xb6fbbf7a)
69 # rlwinm reg, 1, 17, 0, 31
70 self.assertHex(ROTL32(value, 17), 0x7ddfbd5b)
71 self.assertHex(ROTL32(value, 25), 0xdfbd5b7d)
72 self.assertHex(ROTL32(value, 30), 0xf7ab6fbb)
73
74 def assertHex(self, a, b):
75 msg = "{:x} != {:x}".format(a, b)
76 return self.assertEqual(a, b, msg)
77
78 if __name__ == '__main__':
79 unittest.main()