working on adding instructions that take immediates
[power-instruction-analyzer.git] / tests / test_power_instruction_analyzer.py
1 # SPDX-License-Identifier: LGPL-2.1-or-later
2 # See Notices.txt for copyright information
3
4 import unittest
5 import power_instruction_analyzer as pia
6
7
8 class TestOverflowFlags(unittest.TestCase):
9 def test_text_signature(self):
10 self.assertEqual(pia.OverflowFlags.__text_signature__,
11 "(so, ov, ov32)")
12
13 def test_from_to_xer(self):
14 v = pia.OverflowFlags.from_xer(0x186864BDF558B0F6)
15 self.assertEqual(str(v),
16 '{"so":true,"ov":true,"ov32":true}')
17 self.assertEqual(hex(v.to_xer()), '0xc0080000')
18 v = pia.OverflowFlags.from_xer(0x72242678A4DB14BB)
19 self.assertEqual(str(v),
20 '{"so":true,"ov":false,"ov32":true}')
21 self.assertEqual(hex(v.to_xer()), '0x80080000')
22
23 def test_fields(self):
24 v = pia.OverflowFlags(so=False, ov=False, ov32=True)
25 self.assertEqual(v.so, False)
26 self.assertEqual(v.ov, False)
27 self.assertEqual(v.ov32, True)
28 v.so = True
29 self.assertEqual(v.so, True)
30 v.ov = True
31 self.assertEqual(v.ov, True)
32 v.ov32 = False
33 self.assertEqual(v.ov32, False)
34
35 def test_str_repr(self):
36 v = pia.OverflowFlags(so=False, ov=False, ov32=True)
37 self.assertEqual(str(v),
38 '{"so":false,"ov":false,"ov32":true}')
39 self.assertEqual(repr(v),
40 "OverflowFlags(so=False, ov=False, ov32=True)")
41
42
43 class TestCarryFlags(unittest.TestCase):
44 def test_text_signature(self):
45 self.assertEqual(pia.CarryFlags.__text_signature__,
46 "(ca, ca32)")
47
48 def test_from_to_xer(self):
49 v = pia.CarryFlags.from_xer(0x186864BDF558B0F6)
50 self.assertEqual(str(v),
51 '{"ca":true,"ca32":false}')
52 self.assertEqual(hex(v.to_xer()), '0x20000000')
53 v = pia.CarryFlags.from_xer(0xDAF403DEF4ECEBB9)
54 self.assertEqual(str(v),
55 '{"ca":true,"ca32":true}')
56 self.assertEqual(hex(v.to_xer()), '0x20040000')
57 v = pia.CarryFlags.from_xer(0x7B276724952F507F)
58 self.assertEqual(str(v),
59 '{"ca":false,"ca32":true}')
60 self.assertEqual(hex(v.to_xer()), '0x40000')
61
62 def test_fields(self):
63 v = pia.CarryFlags(ca=False, ca32=True)
64 self.assertEqual(v.ca, False)
65 self.assertEqual(v.ca32, True)
66 v.ca = True
67 self.assertEqual(v.ca, True)
68 v.ca32 = False
69 self.assertEqual(v.ca32, False)
70
71 def test_str_repr(self):
72 v = pia.CarryFlags(ca=False, ca32=True)
73 self.assertEqual(str(v),
74 '{"ca":false,"ca32":true}')
75 self.assertEqual(repr(v),
76 "CarryFlags(ca=False, ca32=True)")
77
78
79 class TestConditionRegister(unittest.TestCase):
80 def test_text_signature(self):
81 self.assertEqual(pia.ConditionRegister.__text_signature__,
82 "(lt, gt, eq, so)")
83
84 def test_fields(self):
85 v = pia.ConditionRegister(lt=False, gt=True, eq=False, so=True)
86 self.assertEqual(v.lt, False)
87 self.assertEqual(v.gt, True)
88 self.assertEqual(v.eq, False)
89 self.assertEqual(v.so, True)
90 v.lt = True
91 self.assertEqual(v.lt, True)
92 v.gt = False
93 self.assertEqual(v.gt, False)
94 v.eq = True
95 self.assertEqual(v.eq, True)
96 v.so = False
97 self.assertEqual(v.so, False)
98
99 def test_from_4_bits(self):
100 with self.assertRaises(OverflowError):
101 pia.ConditionRegister.from_4_bits(-1)
102 with self.assertRaisesRegex(OverflowError, "int too big to convert"):
103 pia.ConditionRegister.from_4_bits(0x10)
104 v = pia.ConditionRegister.from_4_bits(0xD)
105 self.assertEqual(str(v),
106 '{"lt":true,"gt":true,"eq":false,"so":true}')
107 v = pia.ConditionRegister.from_4_bits(0x4)
108 self.assertEqual(str(v),
109 '{"lt":false,"gt":true,"eq":false,"so":false}')
110
111 def test_from_cr_field(self):
112 with self.assertRaisesRegex(IndexError, "^field_index out of range$"):
113 pia.ConditionRegister.from_cr_field(0x0, -9)
114 with self.assertRaisesRegex(IndexError, "^field_index out of range$"):
115 pia.ConditionRegister.from_cr_field(0x0, 8)
116 cr = 0x6C42D586
117 values = [
118 '{"lt":false,"gt":true,"eq":true,"so":false}',
119 '{"lt":true,"gt":true,"eq":false,"so":false}',
120 '{"lt":false,"gt":true,"eq":false,"so":false}',
121 '{"lt":false,"gt":false,"eq":true,"so":false}',
122 '{"lt":true,"gt":true,"eq":false,"so":true}',
123 '{"lt":false,"gt":true,"eq":false,"so":true}',
124 '{"lt":true,"gt":false,"eq":false,"so":false}',
125 '{"lt":false,"gt":true,"eq":true,"so":false}',
126 ]
127 for i in range(-8, 8):
128 with self.subTest(i=i):
129 v = pia.ConditionRegister.from_cr_field(cr, i)
130 self.assertEqual(str(v), values[i])
131
132 def test_str_repr(self):
133 v = pia.ConditionRegister(lt=False, gt=True, eq=False, so=True)
134 self.assertEqual(str(v),
135 '{"lt":false,"gt":true,"eq":false,"so":true}')
136 self.assertEqual(repr(v),
137 "ConditionRegister(lt=False, gt=True, eq=False, so=True)")
138
139
140 class TestInstructionInput(unittest.TestCase):
141 def test_text_signature(self):
142 self.assertEqual(pia.InstructionInput.__text_signature__,
143 "(ra=None, rb=None, rc=None, immediate=None, "
144 "carry=None, overflow=None)")
145
146 def test_fields(self):
147 v = pia.InstructionInput(ra=123, rb=456, rc=789)
148 self.assertEqual(v.ra, 123)
149 self.assertEqual(v.rb, 456)
150 self.assertEqual(v.rc, 789)
151 v.ra = 1234
152 self.assertEqual(v.ra, 1234)
153 v.rb = 4567
154 self.assertEqual(v.rb, 4567)
155 v.rc = 7890
156 self.assertEqual(v.rc, 7890)
157 v.immediate = 890
158 self.assertEqual(v.immediate, 890)
159
160 def test_str_repr(self):
161 v = pia.InstructionInput(ra=123, rb=456, rc=789)
162 self.assertEqual(str(v),
163 '{"ra":"0x7B","rb":"0x1C8","rc":"0x315"}')
164 self.assertEqual(repr(v),
165 "InstructionInput(ra=123, rb=456, rc=789, "
166 "immediate=None, carry=None, overflow=None)")
167
168
169 class TestInstructionOutput(unittest.TestCase):
170 maxDiff = 1000
171
172 def test_text_signature(self):
173 self.assertEqual(pia.InstructionOutput.__text_signature__,
174 "(rt=None, overflow=None, carry=None, cr0=None, "
175 "cr1=None, cr2=None, cr3=None, cr4=None, cr5=None, "
176 "cr6=None, cr7=None)")
177
178 def test_fields(self):
179 v = pia.InstructionOutput(
180 overflow=pia.OverflowFlags(so=False, ov=False, ov32=True))
181 self.assertIsNone(v.rt)
182 self.assertIsNone(v.carry)
183 self.assertIsNotNone(v.overflow)
184 self.assertEqual(v.overflow.so, False)
185 self.assertEqual(v.overflow.ov, False)
186 self.assertEqual(v.overflow.ov32, True)
187 self.assertIsNone(v.cr0)
188 self.assertIsNone(v.cr1)
189 self.assertIsNone(v.cr2)
190 self.assertIsNone(v.cr3)
191 self.assertIsNone(v.cr4)
192 self.assertIsNone(v.cr5)
193 self.assertIsNone(v.cr6)
194 self.assertIsNone(v.cr7)
195 v.rt = 123
196 self.assertEqual(v.rt, 123)
197 v.overflow = None
198 self.assertIsNone(v.overflow)
199 v.cr2 = pia.ConditionRegister(lt=False, gt=False, eq=False, so=False)
200 self.assertIsNotNone(v.cr2)
201 v.carry = pia.CarryFlags(ca=False, ca32=True)
202 self.assertIsNotNone(v.carry)
203 self.assertEqual(v.carry.ca, False)
204 self.assertEqual(v.carry.ca32, True)
205
206 def test_str_repr(self):
207 v = pia.InstructionOutput(
208 overflow=pia.OverflowFlags(so=False, ov=False, ov32=True),
209 carry=pia.CarryFlags(ca=True, ca32=False),
210 cr0=pia.ConditionRegister(lt=True, gt=True, eq=True, so=True),
211 cr2=pia.ConditionRegister(lt=False, gt=False, eq=False, so=False))
212 self.assertEqual(str(v),
213 '{"so":false,"ov":false,"ov32":true,"ca":true,'
214 '"ca32":false,"cr0":{"lt":true,"gt":true,"eq":true,'
215 '"so":true},"cr2":{"lt":false,"gt":false,"eq":false,'
216 '"so":false}}')
217 self.assertEqual(repr(v),
218 "InstructionOutput(rt=None, overflow=OverflowFlags("
219 "so=False, ov=False, ov32=True), carry=CarryFlags("
220 "ca=True, ca32=False), cr0=ConditionRegister(lt=True,"
221 " gt=True, eq=True, so=True), cr1=None, "
222 "cr2=ConditionRegister(lt=False, gt=False, eq=False, "
223 "so=False), cr3=None, cr4=None, cr5=None, cr6=None, "
224 "cr7=None)")
225
226
227 class TestDivInstrs(unittest.TestCase):
228 def test(self):
229 v = pia.InstructionInput(
230 ra=0x1234, rb=0x56, rc=0x789,
231 overflow=pia.OverflowFlags(so=False, ov=True, ov32=True),
232 carry=pia.CarryFlags(ca=True, ca32=False))
233 for instr in pia.INSTRS:
234 with self.subTest(instr=instr):
235 fn_name = instr.replace(".", "_")
236 fn = getattr(pia, fn_name)
237 self.assertEqual(fn.__text_signature__, "(inputs)")
238 results = fn(v)
239 self.assertIsInstance(results, pia.InstructionOutput)
240
241 def test_exception(self):
242 with self.assertRaisesRegex(ValueError, "missing instruction input"):
243 v = pia.InstructionInput(ra=1)
244 pia.mulldo_(v)
245 with self.assertRaisesRegex(ValueError, "missing instruction input"):
246 v = pia.InstructionInput(ra=1, rb=1)
247 pia.mulldo_(v)
248
249
250 if __name__ == "__main__":
251 unittest.main()