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