reenable tests
[openpower-isa.git] / src / openpower / decoder / test_fp_working_format.py
1 import unittest
2 from openpower.decoder.fp_working_format import (
3 BFPState, SelectableMSB0Fraction)
4 from fractions import Fraction
5 import math
6
7
8 class TestSelectableMSB0Fraction(unittest.TestCase):
9 def test_repr(self):
10 def check(v, pos, neg):
11 v = Fraction(v)
12 with self.subTest(v=f"{v.numerator:#x} / {v.denominator:#x}",
13 pos=pos, neg=neg):
14 pos = f"SelectableMSB0Fraction({pos})"
15 neg = f"SelectableMSB0Fraction({neg})"
16 self.assertEqual(repr(SelectableMSB0Fraction(v)), pos)
17 self.assertEqual(repr(SelectableMSB0Fraction(-v)), neg)
18 check(0, "0x0.0", "0x0.0")
19 check(1, "0x1.0", "0x...ffff.0 (-0x1)")
20 check(0x2, "0x2.0", "0x...fffe.0 (-0x2)")
21 check(0x4, "0x4.0", "0x...fffc.0 (-0x4)")
22 check(0x8, "0x8.0", "0x...fff8.0 (-0x8)")
23 check(0x10, "0x10.0", "0x...fff0.0 (-0x10)")
24 check(0x100, "0x100.0", "0x...ff00.0 (-0x100)")
25 check(0x1000, "0x1000.0", "0x...f000.0 (-0x1 * 2**12)")
26 check(0x10000,
27 "0x...0000.0 (0x1 * 2**16)", "0x...0000.0 (-0x1 * 2**16)")
28 check(0x100000,
29 "0x...0000.0 (0x1 * 2**20)", "0x...0000.0 (-0x1 * 2**20)")
30 check(0x1000000,
31 "0x...0000.0 (0x1 * 2**24)", "0x...0000.0 (-0x1 * 2**24)")
32 check(Fraction(1, 1 << 1), "0x0.8", "0x...ffff.8 (-0x1 / 0x2)")
33 check(Fraction(1, 1 << 2), "0x0.4", "0x...ffff.c (-0x1 / 0x4)")
34 check(Fraction(1, 1 << 3), "0x0.2", "0x...ffff.e (-0x1 / 0x8)")
35 check(Fraction(1, 1 << 4), "0x0.1", "0x...ffff.f (-0x1 / 0x10)")
36 check(Fraction(1, 1 << 8), "0x0.01", "0x...ffff.ff (-0x1 / 0x100)")
37 check(Fraction(1, 1 << 12), "0x0.001", "0x...ffff.fff (-0x1 * 2**-12)")
38 check(Fraction(1, 1 << 16),
39 "0x0.0001", "0x...ffff.ffff (-0x1 * 2**-16)")
40 check(Fraction(1, 1 << 20),
41 "0x0.0000_1", "0x...ffff.ffff_f (-0x1 * 2**-20)")
42 check(Fraction(1, 1 << 24),
43 "0x0.0000_01", "0x...ffff.ffff_ff (-0x1 * 2**-24)")
44 check(Fraction(1, 1 << 28),
45 "0x0.0000_001", "0x...ffff.ffff_fff (-0x1 * 2**-28)")
46 check(Fraction(1, 1 << 32),
47 "0x0.0000_0001", "0x...ffff.ffff_ffff (-0x1 * 2**-32)")
48 check(Fraction(1, 1 << 36),
49 "0x0.0000_0000_1", "0x...ffff.ffff_ffff_f (-0x1 * 2**-36)")
50 check(Fraction(1, 1 << 40),
51 "0x0.0000_0000_01", "0x...ffff.ffff_ffff_ff (-0x1 * 2**-40)")
52 check(Fraction(1, 1 << 44),
53 "0x0.0000_0000_001", "0x...ffff.ffff_ffff_fff (-0x1 * 2**-44)")
54 check(Fraction(1, 1 << 48),
55 "0x0.0000_0000_0001", "0x...ffff.ffff_ffff_ffff (-0x1 * 2**-48)")
56 check(Fraction(1, 1 << 52),
57 "0x0.0000_0000_0000_1",
58 "0x...ffff.ffff_ffff_ffff_f (-0x1 * 2**-52)")
59 check(Fraction(1, 1 << 56),
60 "0x0.0000_0000_0000_01",
61 "0x...ffff.ffff_ffff_ffff_ff (-0x1 * 2**-56)")
62 check(Fraction(1, 1 << 60),
63 "0x0.0000_0000_0000_001",
64 "0x...ffff.ffff_ffff_ffff_fff (-0x1 * 2**-60)")
65 check(Fraction(1, 1 << 64),
66 "0x0.0000_0000_0000_0001",
67 "0x...ffff.ffff_ffff_ffff_ffff (-0x1 * 2**-64)")
68 check(Fraction(1, 1 << 68),
69 "0x0.0000_0000_0000_0000_1",
70 "0x...ffff.ffff_ffff_ffff_ffff_f (-0x1 * 2**-68)")
71 check(Fraction(1, 1 << 72),
72 "0x0.0000_0000_0000_0000_0... (0x1 * 2**-72)",
73 "0x...ffff.ffff_ffff_ffff_ffff_f... (-0x1 * 2**-72)")
74 check(Fraction(1, 1 << 76),
75 "0x0.0000_0000_0000_0000_0... (0x1 * 2**-76)",
76 "0x...ffff.ffff_ffff_ffff_ffff_f... (-0x1 * 2**-76)")
77 check(Fraction(1, 3),
78 "0x0.5555_5555_5555_5555_5... (0x1 / 0x3)",
79 "0x...ffff.aaaa_aaaa_aaaa_aaaa_a... (-0x1 / 0x3)")
80 check(Fraction(1, 5),
81 "0x0.3333_3333_3333_3333_3... (0x1 / 0x5)",
82 "0x...ffff.cccc_cccc_cccc_cccc_c... (-0x1 / 0x5)")
83 check(Fraction(1, 7),
84 "0x0.2492_4924_9249_2492_4... (0x1 / 0x7)",
85 "0x...ffff.db6d_b6db_6db6_db6d_b... (-0x1 / 0x7)")
86 check(Fraction(1234, 4567),
87 "0x0.452b_c745_e653_bec0_b... (0x4d2 / 0x11d7)",
88 "0x...ffff.bad4_38ba_19ac_413f_4... (-0x4d2 / 0x11d7)")
89 check(Fraction(0x123456789abcdef, 0x1234567),
90 "0x...0079.0000_3840_001a_9640_0... "
91 "(0x123456789abcdef / 0x1234567)",
92 "0x...ff86.ffff_c7bf_ffe5_69bf_f... "
93 "(-0x123456789abcdef / 0x1234567)")
94 # decent approximation to math.tau
95 check(Fraction(312689, 49766),
96 "0x6.487e_d511_4b5c_560c_d... (0x4c571 / 0xc266)",
97 "0x...fff9.b781_2aee_b4a3_a9f3_2... (-0x4c571 / 0xc266)")
98 check(Fraction(0xface0000, 0xffff),
99 "0xface.face_face_face_face_f... (0x539a0000 / 0x5555)",
100 "0x...0531.0531_0531_0531_0531_0... (-0x539a0000 / 0x5555)")
101
102 def test_ops(self):
103 inputs = [1, 4, 6, Fraction(1, 2), Fraction(1, 3), Fraction(2, 3)]
104 inputs.extend([-i for i in inputs])
105 inputs.append(0)
106 for a in inputs:
107 for b in inputs:
108 with self.subTest(a=a, b=b):
109 af = SelectableMSB0Fraction(a)
110 bf = SelectableMSB0Fraction(b)
111 self.assertEqual(af.value, a)
112 self.assertEqual((+af).value, a)
113 self.assertEqual((-af).value, -a)
114 self.assertEqual(math.floor(af).value, math.floor(a))
115 self.assertEqual(math.ceil(af).value, math.ceil(a))
116 self.assertEqual(math.trunc(af).value, math.trunc(a))
117 self.assertEqual(round(af).value, round(a))
118 self.assertEqual((af + bf).value, a + b)
119 self.assertEqual((af - bf).value, a - b)
120 self.assertEqual((af * bf).value, a * b)
121 self.assertEqual(af == bf, a == b)
122 self.assertEqual(af != bf, a != b)
123 self.assertEqual(af < bf, a < b)
124 self.assertEqual(af <= bf, a <= b)
125 self.assertEqual(af > bf, a > b)
126 self.assertEqual(af >= bf, a >= b)
127 if b != 0:
128 self.assertEqual((af / bf).value, a / Fraction(b))
129 self.assertEqual((af // bf).value, a // b)
130 self.assertEqual((af % bf).value, a % b)
131 if isinstance(b, int):
132 if b >= 0:
133 pow2_b = Fraction(1 << b)
134 else:
135 pow2_b = Fraction(1, 1 << -b)
136 self.assertEqual((af << b).value, a * pow2_b)
137 self.assertEqual((af >> b).value, a / pow2_b)
138
139 def slice_helper(self, v, start, length):
140 f = SelectableMSB0Fraction(v)
141 if length > 0:
142 expected = v
143 # expected is 0b...XX.XXXmybitsXXX... where mybits is what we want
144 expected *= 1 << start
145 # expected is 0b...XXm.ybitsXXX...
146 expected *= 1 << (length - 1)
147 # expected is 0b...XXmybits.XX...
148 expected = math.floor(expected)
149 # expected is 0b...XXmybits
150 expected %= 1 << length
151 # expected is 0bmybits
152 else:
153 expected = 0
154 with self.subTest(expected=hex(expected), f=str(f)):
155 self.assertEqual(hex(expected), hex(int(f[start:start+length])))
156 if length == 1:
157 self.assertEqual(hex(expected), hex(int(f[start])))
158 for replace in (0x5555, 0xffff, 0xaaaa, 0):
159 expected = v
160 # expected is 0b...XX.XXXoldbitsYY...
161 # where oldbits is what we want to replace with newbits
162 if length > 0:
163 expected *= 1 << start
164 # expected is 0b...XXo.ldbitsYYY...
165 expected *= 1 << (length - 1)
166 # expected is 0b...XXoldbits.YY...
167 fraction = expected - math.floor(expected)
168 # fraction is 0b.YYY...
169 expected = math.floor(expected)
170 # expected is 0b...XXoldbits
171 expected -= expected % (1 << length)
172 # expected is 0b...XX0000000
173 expected |= replace % (1 << length)
174 # expected is 0b...XXnewbits
175 expected += fraction
176 # expected is 0b...XXnewbits.YY...
177 expected /= 1 << (length - 1)
178 # expected is 0b...XXn.ewbitsYYY...
179 expected /= 1 << start
180 # expected is 0b...XX.XXXnewbitsYY...
181 expected = SelectableMSB0Fraction(expected)
182 with self.subTest(expected=str(expected),
183 replace=hex(replace)):
184 f = SelectableMSB0Fraction(v)
185 f[start:start+length] = replace
186 self.assertEqual(f, expected)
187 if length == 1:
188 f = SelectableMSB0Fraction(v)
189 f[start] = replace
190 self.assertEqual(f, expected)
191
192 def test_slice(self):
193 for v in [Fraction(0xface0000, 0xffff), Fraction(0x1230000, 0xffff)]:
194 for start in range(0, 17):
195 for length in reversed(range(0, 17)):
196 with self.subTest(v=v, start=start, length=length):
197 self.slice_helper(v, start, length)
198
199
200 if __name__ == "__main__":
201 unittest.main()