5e1f1a1d5d21ffa320896765aa7ee72145baf00f
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_svp64_bc.py
1 from nmigen import Module, Signal
2 from nmigen.sim import Simulator, Delay, Settle
3 from nmutil.formaltest import FHDLTestCase
4 import unittest
5 from openpower.decoder.isa.caller import ISACaller
6 from openpower.decoder.power_decoder import (create_pdecode)
7 from openpower.decoder.power_decoder2 import (PowerDecode2)
8 from openpower.simulator.program import Program
9 from openpower.decoder.isa.caller import ISACaller, SVP64State
10 from openpower.decoder.selectable_int import SelectableInt
11 from openpower.decoder.orderedset import OrderedSet
12 from openpower.decoder.isa.all import ISA
13 from openpower.decoder.isa.test_caller import Register, run_tst
14 from openpower.sv.trans.svp64 import SVP64Asm
15 from openpower.consts import SVP64CROffs
16 from copy import deepcopy
17
18
19 class DecoderTestCase(FHDLTestCase):
20
21 def _check_regs(self, sim, expected):
22 for i in range(32):
23 self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
24
25 def test_sv_load_store(self):
26 """>>> lst = ["addi 2, 0, 0x0010",
27 "addi 3, 0, 0x0008",
28 "addi 6, 0, 0x1234",
29 "addi 7, 0, 0x1235",
30 "sv.stw *6, 0(*2)",
31 "sv.lwz *8, 0(*2)"]
32 """
33 lst = SVP64Asm(["addi 2, 0, 0x0010",
34 "addi 3, 0, 0x0008",
35 "addi 6, 0, 0x1234",
36 "addi 7, 0, 0x1235",
37 "sv.stw *6, 0(*2)",
38 "sv.lwz *8, 0(*2)"])
39 lst = list(lst)
40
41 # SVSTATE (in this case, VL=2)
42 svstate = SVP64State()
43 svstate.vl = 2 # VL
44 svstate.maxvl = 2 # MAXVL
45 print ("SVSTATE", bin(svstate.asint()))
46
47 with Program(lst, bigendian=False) as program:
48 sim = self.run_tst_program(program, svstate=svstate)
49 print(sim.gpr(1))
50 self.assertEqual(sim.gpr(8), SelectableInt(0x1234, 64))
51 self.assertEqual(sim.gpr(9), SelectableInt(0x1235, 64))
52
53 def test_sv_branch_cond(self):
54 for i in [0, 10]: #, 10]: #[0, 10]:
55 lst = SVP64Asm(
56 [f"addi 1, 0, {i}", # set r1 to i
57 f"addi 2, 0, {i}", # set r2 to i
58 "cmpi cr0, 1, 1, 10", # compare r1 with 10 and store to cr0
59 "cmpi cr1, 1, 2, 10", # compare r2 with 10 and store to cr1
60 "sv.bc 12, *2, 0xc", # beq 0xc -
61 # branch if r1 equals 10 to the nop below
62 "addi 3, 0, 0x1234", # if r1 == 10 this shouldn't execute
63 "or 0, 0, 0"] # branch target
64 )
65 lst = list(lst)
66
67 # SVSTATE (in this case, VL=2)
68 svstate = SVP64State()
69 svstate.vl = 2 # VL
70 svstate.maxvl = 2 # MAXVL
71 print ("SVSTATE", bin(svstate.asint()))
72
73 with Program(lst, bigendian=False) as program:
74 sim = self.run_tst_program(program, svstate=svstate)
75 if i == 10:
76 self.assertEqual(sim.gpr(3), SelectableInt(0, 64))
77 else:
78 self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
79
80 def test_sv_branch_cond_all(self):
81 for i in [7, 8, 9]:
82 lst = SVP64Asm(
83 [f"addi 1, 0, {i+1}", # set r1 to i
84 f"addi 2, 0, {i}", # set r2 to i
85 "cmpi cr0, 1, 1, 8", # compare r1 with 10 and store to cr0
86 "cmpi cr1, 1, 2, 8", # compare r2 with 10 and store to cr1
87 "sv.bc/all 12, *1, 0xc", # bgt 0xc - branch if BOTH
88 # r1 AND r2 greater 8 to the nop below
89 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
90 "or 0, 0, 0"] # branch target
91 )
92 lst = list(lst)
93
94 # SVSTATE (in this case, VL=2)
95 svstate = SVP64State()
96 svstate.vl = 2 # VL
97 svstate.maxvl = 2 # MAXVL
98 print ("SVSTATE", bin(svstate.asint()))
99
100 with Program(lst, bigendian=False) as program:
101 sim = self.run_tst_program(program, svstate=svstate)
102 if i == 9:
103 self.assertEqual(sim.gpr(3), SelectableInt(0, 64))
104 else:
105 self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
106
107 def test_sv_branch_cond_all_vlset(self):
108 for i in [7, 8, 9]:
109 lst = SVP64Asm(
110 [f"addi 1, 0, {i+1}", # set r1 to i
111 f"addi 2, 0, {i}", # set r2 to i
112 "cmpi cr0, 1, 1, 8", # compare r1 with 10 and store to cr0
113 "cmpi cr1, 1, 2, 8", # compare r2 with 10 and store to cr1
114 "sv.bc/all/vs 12, *1, 0xc", # bgt 0xc - branch if BOTH
115 # r1 AND r2 greater 8 to the nop below
116 # also truncate VL at the fail-point
117 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
118 "or 0, 0, 0"] # branch target
119 )
120 lst = list(lst)
121
122 # SVSTATE (in this case, VL=2)
123 svstate = SVP64State()
124 svstate.vl = 2 # VL
125 svstate.maxvl = 2 # MAXVL
126 print ("SVSTATE", bin(svstate.asint()))
127
128 with Program(lst, bigendian=False) as program:
129 sim = self.run_tst_program(program, svstate=svstate)
130 if i == 9:
131 self.assertEqual(sim.gpr(3), SelectableInt(0, 64))
132 else:
133 self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
134 print ("SVSTATE.vl", bin(svstate.vl))
135 self.assertEqual(svstate.vl, i-7)
136
137 def test_sv_branch_cond_vlset_inv(self):
138 for i in [7, 8, 9]:
139 lst = SVP64Asm(
140 [f"addi 1, 0, {i+1}", # set r1 to i
141 f"addi 2, 0, {i}", # set r2 to i
142 "cmpi cr0, 1, 1, 8", # compare r1 with 8 and store to cr0
143 "cmpi cr1, 1, 2, 8", # compare r2 with 8 and store to cr1
144 "sv.bc/vsb 4, *1, 0xc", # bgt 0xc - branch if BOTH
145 # r1 AND r2 greater 8 to the nop below
146 # also truncate VL at the fail-point
147 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
148 "or 0, 0, 0"] # branch target
149 )
150 lst = list(lst)
151
152 # SVSTATE (in this case, VL=2)
153 svstate = SVP64State()
154 svstate.vl = 2 # VL
155 svstate.maxvl = 2 # MAXVL
156 print ("SVSTATE", bin(svstate.asint()))
157
158 with self.subTest("vlset_inv %d" % i):
159 with Program(lst, bigendian=False) as program:
160 sim = self.run_tst_program(program, svstate=svstate)
161 print ("SVSTATE.vl", bin(svstate.vl))
162 if i == 9:
163 self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
164 else:
165 self.assertEqual(sim.gpr(3), SelectableInt(0, 64))
166 self.assertEqual(svstate.vl, i-7)
167
168 def test_sv_branch_cond_ctr_vlset_inv(self):
169 for i in [7, 8, 9]:
170 lst = SVP64Asm(
171 [f"addi 1, 0, {i+1}", # set r1 to i
172 f"addi 2, 0, {i}", # set r2 to i
173 "cmpi cr0, 1, 1, 8", # compare r1 with 8 and store to cr0
174 "cmpi cr1, 1, 2, 8", # compare r2 with 8 and store to cr1
175 "sv.bc/vsb 0, *1, 0xc", # bgt 0xc - branch if BOTH
176 # r1 AND r2 greater 8 to the nop below
177 # also truncate VL at the fail-point
178 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
179 "or 0, 0, 0"] # branch target
180 )
181 lst = list(lst)
182
183 # SVSTATE (in this case, VL=2)
184 svstate = SVP64State()
185 svstate.vl = 2 # VL
186 svstate.maxvl = 2 # MAXVL
187 print ("SVSTATE", bin(svstate.asint()))
188 sprs = {'CTR': i}
189
190 with self.subTest("vlset_ctr_inv %d" % i):
191 with Program(lst, bigendian=False) as program:
192 sim = self.run_tst_program(program, svstate=svstate,
193 initial_sprs=sprs)
194 print ("SVSTATE.vl", bin(svstate.vl))
195 print ("CTR", sim.spr('CTR').value)
196 if i == 9:
197 self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
198 else:
199 self.assertEqual(sim.gpr(3), SelectableInt(0, 64))
200 self.assertEqual(svstate.vl, i-7)
201
202 def test_sv_branch_ctr(self):
203 """XXX under development, seems to be good.
204 basically this will reduce CTR under a *vector* loop, where BO[0]
205 is 1 so there is no CR-bit-test, and BO[2] is 0 so there is a CTR-zero
206 test. when the CTR-zero test fails the loop is exited, with CTR
207 having been reduced by up to at least VL times. without VLSET
208 mode at the same time (which truncates VL at this same fail-point)
209 however this is not necessarily so useful, but at least the branch
210 occurs with CTR being reduced *at least* by VL.
211 """
212 for i in [1,2,3]:
213 lst = SVP64Asm(
214 [
215 "sv.bc/ctr/all 16, *0, 0xc", # branch, test CTR, reducing by VL
216 "addi 3, 0, 0x1234", # if tests fail this shouldn't execute
217 "or 0, 0, 0"] # branch target
218 )
219 lst = list(lst)
220
221 # SVSTATE (in this case, VL=2)
222 svstate = SVP64State()
223 svstate.vl = 2 # VL
224 svstate.maxvl = 2 # MAXVL
225 print ("SVSTATE", bin(svstate.asint()))
226 sprs = {'CTR': i}
227
228 with Program(lst, bigendian=False) as program:
229 sim = self.run_tst_program(program, svstate=svstate,
230 initial_sprs=sprs)
231 sim.gpr.dump()
232 sim.spr.dump()
233 if i != 3:
234 self.assertEqual(sim.gpr(3), SelectableInt(0x1234, 64))
235 self.assertEqual(sim.spr('CTR'), SelectableInt(0, 64))
236 else:
237 self.assertEqual(sim.gpr(3), SelectableInt(0, 64))
238 self.assertEqual(sim.spr('CTR'), SelectableInt(1, 64))
239
240 def test_sv_branch_ctr_loop(self):
241 """this is a branch-ctr-loop demo which shows an (unconditional)
242 decrementing of CTR by VL. BI still has to be set to Vector even
243 though it is unused (BO[0]=1).
244 """
245 maxvl = 4
246 lst = SVP64Asm(
247 [
248 "setvl 1, 0, %d, 0, 1, 1" % maxvl, # VL (and r1) = MIN(CTR,MAXVL=4)
249 "add 2, 2, 1", # for fun accumulate r1 (VL) into r2
250 "sv.bc/all 16, *0, -0x8", # branch, test CTR, reducing by VL
251 ]
252 )
253 lst = list(lst)
254
255 # SVSTATE - set vl and maxvl to 2, they get overridden with setvl
256 svstate = SVP64State()
257 svstate.vl = 2 # VL
258 svstate.maxvl = 2 # MAXVL
259 print ("SVSTATE", bin(svstate.asint()))
260 target = 15
261 sprs = {'CTR': target}
262
263 with Program(lst, bigendian=False) as program:
264 sim = self.run_tst_program(program, svstate=svstate,
265 initial_sprs=sprs)
266 sim.gpr.dump()
267 sim.spr.dump()
268 self.assertEqual(sim.spr('CTR'), SelectableInt(0, 64))
269 self.assertEqual(sim.gpr(2), SelectableInt(target, 64))
270 # MAXVL repeatedly subtracted from VL (r1), last loop has remainder
271 self.assertEqual(sim.gpr(1), SelectableInt(target % maxvl, 64))
272
273 def norun_sv_add_cr(self):
274 """>>> lst = ['sv.add. *1, *5, *9'
275 ]
276
277 adds when Rc=1: TODO CRs higher up
278 * 1 = 5 + 9 => 0 = -1+1 CR0=0b100
279 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 CR1=0b010
280 """
281 isa = SVP64Asm(['sv.add. *1, *5, *9'
282 ])
283 lst = list(isa)
284 print ("listing", lst)
285
286 # initial values in GPR regfile
287 initial_regs = [0] * 32
288 initial_regs[9] = 0xffffffffffffffff
289 initial_regs[10] = 0x1111
290 initial_regs[5] = 0x1
291 initial_regs[6] = 0x2223
292 # SVSTATE (in this case, VL=2)
293 svstate = SVP64State()
294 svstate.vl = 2 # VL
295 svstate.maxvl = 2 # MAXVL
296 print ("SVSTATE", bin(svstate.asint()))
297 # copy before running
298 expected_regs = deepcopy(initial_regs)
299 expected_regs[1] = initial_regs[5] + initial_regs[9] # 0x0
300 expected_regs[2] = initial_regs[6] + initial_regs[10] # 0x3334
301
302 with Program(lst, bigendian=False) as program:
303 sim = self.run_tst_program(program, initial_regs, svstate)
304 # XXX TODO, these need to move to higher range (offset)
305 cr0_idx = SVP64CROffs.CR0
306 cr1_idx = SVP64CROffs.CR1
307 CR0 = sim.crl[cr0_idx].get_range().value
308 CR1 = sim.crl[cr1_idx].get_range().value
309 print ("CR0", CR0)
310 print ("CR1", CR1)
311 self._check_regs(sim, expected_regs)
312 self.assertEqual(CR0, SelectableInt(2, 4))
313 self.assertEqual(CR1, SelectableInt(4, 4))
314
315 def run_tst_program(self, prog, initial_regs=None,
316 svstate=None,
317 initial_sprs=None):
318 if initial_regs is None:
319 initial_regs = [0] * 32
320 simulator = run_tst(prog, initial_regs, svstate=svstate,
321 initial_sprs=initial_sprs)
322 simulator.gpr.dump()
323 return simulator
324
325
326 if __name__ == "__main__":
327 unittest.main()