add divde regression test
[soc.git] / src / soc / fu / div / test / test_pipe_caller.py
1 import random
2 import unittest
3 from soc.simulator.program import Program
4 from soc.config.endian import bigendian
5
6 from soc.fu.test.common import (TestCase, TestAccumulatorBase, skip_case)
7 from soc.fu.div.pipe_data import DivPipeKind
8
9 from soc.fu.div.test.helper import (log_rand, get_cu_inputs,
10 set_alu_inputs, DivTestHelper)
11
12
13 class DivTestCases(TestAccumulatorBase):
14 def case_divde_regression(self):
15 lst = ["divde 3, 1, 2"]
16 initial_regs = [0] * 32
17 initial_regs[2] = 0x1
18 with Program(lst, bigendian) as prog:
19 self.add_case(prog, initial_regs)
20
21 def case_moduw_regression(self):
22 lst = ["moduw 3, 1, 2"]
23 initial_regs = [0] * 32
24 initial_regs[1] = 0x1
25 initial_regs[2] = 0xffffffffffffffff
26 with Program(lst, bigendian) as prog:
27 self.add_case(prog, initial_regs)
28
29 def case_modsw_regression(self):
30 lst = ["modsw 3, 1, 2"]
31 initial_regs = [0] * 32
32 initial_regs[1] = 0xffffffffffffffff
33 initial_regs[2] = 0x2
34 with Program(lst, bigendian) as prog:
35 self.add_case(prog, initial_regs)
36
37 def case_divweu_regression(self):
38 # simulator is wrong, FSM and power-instruction-analyzer both correct
39 lst = ["divweu 3, 1, 2"]
40 initial_regs = [0] * 32
41 initial_regs[1] = 0x1
42 initial_regs[2] = 0xffffffffffffffff
43 with Program(lst, bigendian) as prog:
44 self.add_case(prog, initial_regs)
45
46 def case_divwe_regression(self):
47 # div FU and power-instruction-analyzer both correctly return 0
48 # hitting behavior undefined by Power v3.1 spec, need to adjust
49 # simulator API to tell tests that the simulator's output doesn't
50 # need to completely match
51 lst = [f"divwe 3, 1, 2"]
52 initial_regs = [0] * 32
53 initial_regs[1] = 1
54 initial_regs[2] = 1
55 with Program(lst, bigendian) as prog:
56 self.add_case(prog, initial_regs)
57
58 def case_divwe__regression(self):
59 lst = ["divwe. 3, 1, 2"]
60 initial_regs = [0] * 32
61 with Program(lst, bigendian) as prog:
62 self.add_case(prog, initial_regs)
63
64 def case_divw_regression(self):
65 # simulator is wrong, FSM and power-instruction-analyzer both correct
66 lst = [f"divw 0, 1, 2"]
67 initial_regs = [0] * 32
68 initial_regs[2] = 0x2
69 initial_regs[1] = 0x80000000
70 with Program(lst, bigendian) as prog:
71 self.add_case(prog, initial_regs)
72
73 # modulo
74 def case_modsd_regression2(self):
75 lst = [f"modsd 0, 1, 2"]
76 initial_regs = [0] * 32
77 initial_regs[2] = 0xff
78 initial_regs[1] = 0x7fffffffffffffff
79 with Program(lst, bigendian) as prog:
80 self.add_case(prog, initial_regs)
81
82 # modulo
83 def case_modsd_regression(self):
84 lst = [f"modsd 17, 27, 0"]
85 initial_regs = [0] * 32
86 initial_regs[0] = 0xff
87 initial_regs[27] = 0x7fffffffffffffff
88 with Program(lst, bigendian) as prog:
89 self.add_case(prog, initial_regs)
90
91 def case_divduo_regression(self):
92 lst = [f"divduo. 11, 20, 6"]
93 initial_regs = [0] * 32
94 # gpr: 00ff00ff00ff0080 <- r6
95 # gpr: 000000000000007f <- r11
96 # gpr: 7f6e5d4c3b2a1908 <- r20
97 initial_regs[6] = 0x00ff00ff00ff0080
98 initial_regs[20] = 0x7f6e5d4c3b2a1908
99 with Program(lst, bigendian) as prog:
100 self.add_case(prog, initial_regs)
101
102 def case_0_regression(self):
103 for i in range(40):
104 lst = ["divwo 3, 1, 2"]
105 initial_regs = [0] * 32
106 initial_regs[1] = 0xbc716835f32ac00c
107 initial_regs[2] = 0xcdf69a7f7042db66
108 with Program(lst, bigendian) as prog:
109 self.add_case(prog, initial_regs)
110
111 def case_1_regression(self):
112 lst = ["divwo 3, 1, 2"]
113 initial_regs = [0] * 32
114 initial_regs[1] = 0x10000000000000000-4
115 initial_regs[2] = 0x10000000000000000-2
116 with Program(lst, bigendian) as prog:
117 self.add_case(prog, initial_regs)
118
119 def case_2_regression(self):
120 lst = ["divwo 3, 1, 2"]
121 initial_regs = [0] * 32
122 initial_regs[1] = 0xffffffffffff9321
123 initial_regs[2] = 0xffffffffffff7012
124 with Program(lst, bigendian) as prog:
125 self.add_case(prog, initial_regs)
126
127 def case_3_regression(self):
128 lst = ["divwo. 3, 1, 2"]
129 initial_regs = [0] * 32
130 initial_regs[1] = 0x1b8e32f2458746af
131 initial_regs[2] = 0x6b8aee2ccf7d62e9
132 with Program(lst, bigendian) as prog:
133 self.add_case(prog, initial_regs)
134
135 def case_4_regression(self):
136 lst = ["divw 3, 1, 2"]
137 initial_regs = [0] * 32
138 initial_regs[1] = 0x1c4e6c2f3aa4a05c
139 initial_regs[2] = 0xe730c2eed6cc8dd7
140 with Program(lst, bigendian) as prog:
141 self.add_case(prog, initial_regs)
142
143 def case_5_regression(self):
144 lst = ["divw 3, 1, 2",
145 "divwo. 6, 4, 5"]
146 initial_regs = [0] * 32
147 initial_regs[1] = 0x1c4e6c2f3aa4a05c
148 initial_regs[2] = 0xe730c2eed6cc8dd7
149 initial_regs[4] = 0x1b8e32f2458746af
150 initial_regs[5] = 0x6b8aee2ccf7d62e9
151 with Program(lst, bigendian) as prog:
152 self.add_case(prog, initial_regs)
153
154 def case_6_regression(self):
155 # CR0 not getting set properly for this one
156 # turns out that overflow is not set correctly in
157 # fu/div/output_stage.py calc_overflow
158 # https://bugs.libre-soc.org/show_bug.cgi?id=425
159 lst = ["divw. 3, 1, 2"]
160 initial_regs = [0] * 32
161 initial_regs[1] = 0x61c1cc3b80f2a6af
162 initial_regs[2] = 0x9dc66a7622c32bc0
163 with Program(lst, bigendian) as prog:
164 self.add_case(prog, initial_regs)
165
166 def case_7_regression(self):
167 # https://bugs.libre-soc.org/show_bug.cgi?id=425
168 lst = ["divw. 3, 1, 2"]
169 initial_regs = [0] * 32
170 initial_regs[1] = 0xf1791627e05e8096
171 initial_regs[2] = 0xffc868bf4573da0b
172 with Program(lst, bigendian) as prog:
173 self.add_case(prog, initial_regs)
174
175 def case_8_fsm_regression(self): # FSM result is "36" not 6
176 lst = ["divwu. 3, 1, 2"]
177 initial_regs = [0] * 32
178 initial_regs[1] = 18
179 initial_regs[2] = 3
180 with Program(lst, bigendian) as prog:
181 self.add_case(prog, initial_regs)
182
183 def case_9_regression(self): # CR0 fails: expected 0b10, actual 0b11
184 lst = ["divw. 3, 1, 2"]
185 initial_regs = [0] * 32
186 initial_regs[1] = 1
187 initial_regs[2] = 0
188 with Program(lst, bigendian) as prog:
189 self.add_case(prog, initial_regs)
190
191 def case_10_regression(self): # overflow fails
192 lst = ["divwo 3, 1, 2"]
193 initial_regs = [0] * 32
194 initial_regs[1] = 0xbc716835f32ac00c
195 initial_regs[2] = 0xcdf69a7f7042db66
196 with Program(lst, bigendian) as prog:
197 self.add_case(prog, initial_regs)
198
199 def case_11_regression(self):
200 lst = ["divwo. 3, 1, 2"]
201 initial_regs = [0] * 32
202 initial_regs[1] = 0xffffffffffffffff
203 initial_regs[2] = 0xffffffffffffffff
204 with Program(lst, bigendian) as prog:
205 self.add_case(prog, initial_regs)
206
207 def case_divw_by_zero_1(self):
208 lst = ["divw. 3, 1, 2"]
209 initial_regs = [0] * 32
210 initial_regs[1] = 0x1
211 initial_regs[2] = 0x0
212 with Program(lst, bigendian) as prog:
213 self.add_case(prog, initial_regs)
214
215 def case_divw_overflow2(self):
216 lst = ["divw. 3, 1, 2"]
217 initial_regs = [0] * 32
218 initial_regs[1] = 0x80000000
219 initial_regs[2] = 0xffffffffffffffff # top bits don't seem to matter
220 with Program(lst, bigendian) as prog:
221 self.add_case(prog, initial_regs)
222
223 def case_divw_overflow3(self):
224 lst = ["divw. 3, 1, 2"]
225 initial_regs = [0] * 32
226 initial_regs[1] = 0x80000000
227 initial_regs[2] = 0xffffffff
228 with Program(lst, bigendian) as prog:
229 self.add_case(prog, initial_regs)
230
231 def case_divwuo_regression_1(self):
232 lst = ["divwuo. 3, 1, 2"]
233 initial_regs = [0] * 32
234 initial_regs[1] = 0x7591a398c4e32b68
235 initial_regs[2] = 0x48674ab432867d69
236 with Program(lst, bigendian) as prog:
237 self.add_case(prog, initial_regs)
238
239 def case_divwuo_1(self):
240 lst = ["divwuo. 3, 1, 2"]
241 initial_regs = [0] * 32
242 initial_regs[1] = 0x50
243 initial_regs[2] = 0x2
244 with Program(lst, bigendian) as prog:
245 self.add_case(prog, initial_regs)
246
247 def case_rand_divwu(self):
248 insns = ["divwu", "divwu.", "divwuo", "divwuo."]
249 for i in range(40):
250 choice = random.choice(insns)
251 lst = [f"{choice} 3, 1, 2"]
252 initial_regs = [0] * 32
253 initial_regs[1] = log_rand(32)
254 initial_regs[2] = log_rand(32)
255 with Program(lst, bigendian) as prog:
256 self.add_case(prog, initial_regs)
257
258 def case_rand_divw(self):
259 insns = ["divw", "divw.", "divwo", "divwo."]
260 for i in range(40):
261 choice = random.choice(insns)
262 lst = [f"{choice} 3, 1, 2"]
263 initial_regs = [0] * 32
264 initial_regs[1] = log_rand(32)
265 initial_regs[2] = log_rand(32)
266 with Program(lst, bigendian) as prog:
267 self.add_case(prog, initial_regs)
268
269
270 class TestPipe(DivTestHelper):
271 def test_div_pipe_core(self):
272 self.run_all(DivTestCases().test_data,
273 DivPipeKind.DivPipeCore, "div_pipe_caller")
274
275 def test_fsm_div_core(self):
276 self.run_all(DivTestCases().test_data,
277 DivPipeKind.FSMDivCore, "div_pipe_caller")
278
279 def test_sim_only(self):
280 self.run_all(DivTestCases().test_data,
281 DivPipeKind.SimOnly, "div_pipe_caller")
282
283
284 if __name__ == "__main__":
285 unittest.main()