9cb43b269f568a0df3688e975587523c59e58709
[soc.git] / src / soc / decoder / helpers.py
1 import unittest
2 from soc.decoder.selectable_int import SelectableInt
3
4
5 def exts(value, bits):
6 sign = 1 << (bits - 1)
7 return (value & (sign - 1)) - (value & sign)
8
9
10 def EXTS(value):
11 """ extends sign bit out from current MSB to all 256 bits
12 """
13 assert isinstance(value, SelectableInt)
14 return exts(value.value, value.bits)
15
16 def EXTS64(value):
17 """ extends sign bit out from current MSB to 64 bits
18 """
19 assert isinstance(value, SelectableInt)
20 return SelectableInt(exts(value.value, value.bits) & ((1 << 64)-1), 64)
21
22
23 # XXX should this explicitly extend from 32 to 64?
24 def EXTZ64(value):
25 if isinstance(value, SelectableInt):
26 value = value.value
27 return SelectableInt(value & ((1<<32)-1), 64)
28
29
30 def rotl(value, bits, wordlen):
31 mask = (1 << wordlen) - 1
32 bits = bits & (wordlen - 1)
33 return ((value << bits) | (value >> (wordlen-bits))) & mask
34
35
36 def ROTL64(value, bits):
37 return rotl(value, bits, 64)
38
39
40 def ROTL32(value, bits):
41 return rotl(value, bits, 32)
42
43
44 def MASK(x, y):
45 if x < y:
46 x = 64-x
47 y = 63-y
48 mask_a = ((1 << x) - 1) & ((1 << 64) - 1)
49 mask_b = ((1 << y) - 1) & ((1 << 64) - 1)
50 else:
51 x = 64-x
52 y = 63-y
53 mask_a = ((1 << x) - 1) & ((1 << 64) - 1)
54 mask_b = (~((1 << y) - 1)) & ((1 << 64) - 1)
55 return mask_a ^ mask_b
56
57
58 # For these tests I tried to find power instructions that would let me
59 # isolate each of these helper operations. So for instance, when I was
60 # testing the MASK() function, I chose rlwinm and rldicl because if I
61 # set the shift equal to 0 and passed in a value of all ones, the
62 # result I got would be exactly the same as the output of MASK()
63
64 class HelperTests(unittest.TestCase):
65 def test_MASK(self):
66 # Verified using rlwinm, rldicl, rldicr in qemu
67 # li 1, -1
68 # rlwinm reg, 1, 0, 5, 15
69 self.assertHex(MASK(5+32, 15+32), 0x7ff0000)
70 # rlwinm reg, 1, 0, 15, 5
71 self.assertHex(MASK(15+32, 5+32), 0xfffffffffc01ffff)
72 self.assertHex(MASK(30+32, 2+32), 0xffffffffe0000003)
73 # rldicl reg, 1, 0, 37
74 self.assertHex(MASK(37, 63), 0x7ffffff)
75 self.assertHex(MASK(10, 63), 0x3fffffffffffff)
76 self.assertHex(MASK(58, 63), 0x3f)
77 # rldicr reg, 1, 0, 37
78 self.assertHex(MASK(0, 37), 0xfffffffffc000000)
79 self.assertHex(MASK(0, 10), 0xffe0000000000000)
80 self.assertHex(MASK(0, 58), 0xffffffffffffffe0)
81
82 def test_ROTL64(self):
83 # r1 = 0xdeadbeef12345678
84 value = 0xdeadbeef12345678
85
86 # rldicl reg, 1, 10, 0
87 self.assertHex(ROTL64(value, 10), 0xb6fbbc48d159e37a)
88 # rldicl reg, 1, 35, 0
89 self.assertHex(ROTL64(value, 35), 0x91a2b3c6f56df778)
90 self.assertHex(ROTL64(value, 58), 0xe37ab6fbbc48d159)
91 self.assertHex(ROTL64(value, 22), 0xbbc48d159e37ab6f)
92
93 def test_ROTL32(self):
94 # r1 = 0xdeadbeef
95 value = 0xdeadbeef
96
97 # rlwinm reg, 1, 10, 0, 31
98 self.assertHex(ROTL32(value, 10), 0xb6fbbf7a)
99 # rlwinm reg, 1, 17, 0, 31
100 self.assertHex(ROTL32(value, 17), 0x7ddfbd5b)
101 self.assertHex(ROTL32(value, 25), 0xdfbd5b7d)
102 self.assertHex(ROTL32(value, 30), 0xf7ab6fbb)
103
104 def test_EXTS64(self):
105 value_a = 0xdeadbeef # r1
106 value_b = 0x73123456 # r2
107 value_c = 0x80000000 # r3
108
109 # extswsli reg, 1, 0
110 self.assertHex(EXTS64(value_a), 0xffffffffdeadbeef)
111 # extswsli reg, 2, 0
112 self.assertHex(EXTS64(value_b), value_b)
113 # extswsli reg, 3, 0
114 self.assertHex(EXTS64(value_c), 0xffffffff80000000)
115
116 def assertHex(self, a, b):
117 msg = "{:x} != {:x}".format(a, b)
118 return self.assertEqual(a, b, msg)
119
120
121 if __name__ == '__main__':
122 unittest.main()