2 from copy
import deepcopy
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
.insndb
.asm
import SVP64Asm
13 class DecoderTestCase(FHDLTestCase
):
15 def _check_regs(self
, sim
, expected
):
17 self
.assertEqual(sim
.gpr(i
), SelectableInt(expected
[i
], 64))
19 def test_sv_load_store(self
):
20 """>>> lst = ["addi 2, 0, 0x0010",
27 lst
= SVP64Asm(["addi 2, 0, 0x0010",
35 # SVSTATE (in this case, VL=2)
36 svstate
= SVP64State()
38 svstate
.maxvl
= 2 # MAXVL
39 print("SVSTATE", bin(svstate
.asint()))
41 with
Program(lst
, bigendian
=False) as program
:
42 sim
= self
.run_tst_program(program
, svstate
=svstate
)
44 self
.assertEqual(sim
.gpr(8), SelectableInt(0x1234, 64))
45 self
.assertEqual(sim
.gpr(9), SelectableInt(0x1235, 64))
47 def test_sv_branch_cond(self
):
48 for i
in [0, 10]: # , 10]: #[0, 10]:
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
61 # SVSTATE (in this case, VL=2)
62 svstate
= SVP64State()
64 svstate
.maxvl
= 2 # MAXVL
65 print("SVSTATE", bin(svstate
.asint()))
67 with
Program(lst
, bigendian
=False) as program
:
68 sim
= self
.run_tst_program(program
, svstate
=svstate
)
70 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
72 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
74 def test_sv_branch_cond_all(self
):
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
88 # SVSTATE (in this case, VL=2)
89 svstate
= SVP64State()
91 svstate
.maxvl
= 2 # MAXVL
92 print("SVSTATE", bin(svstate
.asint()))
94 with
Program(lst
, bigendian
=False) as program
:
95 sim
= self
.run_tst_program(program
, svstate
=svstate
)
97 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
99 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
101 def test_sv_branch_cond_all_vlset(self
):
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
116 # SVSTATE (in this case, VL=2)
117 svstate
= SVP64State()
119 svstate
.maxvl
= 2 # MAXVL
120 print("SVSTATE", bin(svstate
.asint()))
122 with
Program(lst
, bigendian
=False) as program
:
123 sim
= self
.run_tst_program(program
, svstate
=svstate
)
125 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
127 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
128 print("SVSTATE.vl", bin(svstate
.vl
))
129 self
.assertEqual(svstate
.vl
, i
-7)
131 def test_sv_branch_cond_vlset_inv(self
):
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
146 # SVSTATE (in this case, VL=2)
147 svstate
= SVP64State()
149 svstate
.maxvl
= 2 # MAXVL
150 print("SVSTATE", bin(svstate
.asint()))
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
))
157 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
159 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
160 self
.assertEqual(svstate
.vl
, i
-7)
162 def test_sv_branch_cond_ctr_vlset_inv(self
):
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
177 # SVSTATE (in this case, VL=2)
178 svstate
= SVP64State()
180 svstate
.maxvl
= 2 # MAXVL
181 print("SVSTATE", bin(svstate
.asint()))
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
,
188 print("SVSTATE.vl", bin(svstate
.vl
))
189 print("CTR", sim
.spr('CTR').value
)
191 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
193 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
194 self
.assertEqual(svstate
.vl
, i
-7)
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.
208 "sv.bc/ctr/all 16, *0, 0xc", # branch, test CTR, reducing by VL
209 "addi 3, 0, 0x1234", # if tests fail shouldn't execute
210 "or 0, 0, 0" # branch target
214 # SVSTATE (in this case, VL=2)
215 svstate
= SVP64State()
217 svstate
.maxvl
= 2 # MAXVL
218 print("SVSTATE", bin(svstate
.asint()))
221 with
Program(lst
, bigendian
=False) as program
:
222 sim
= self
.run_tst_program(program
, svstate
=svstate
,
227 self
.assertEqual(sim
.gpr(3), SelectableInt(0x1234, 64))
228 self
.assertEqual(sim
.spr('CTR'), SelectableInt(0, 64))
230 self
.assertEqual(sim
.gpr(3), SelectableInt(0, 64))
231 self
.assertEqual(sim
.spr('CTR'), SelectableInt(1, 64))
233 def test_sv_branch_ctr_loop(self
):
234 """this is a branch-ctr-loop demo which shows an (unconditional)
235 decrementing of CTR by VL. BI still has to be set to Vector even
236 though it is unused (BO[0]=1).
241 # VL (and r1) = MIN(CTR,MAXVL=4)
242 "setvl 1, 0, %d, 0, 1, 1" % maxvl
,
243 "add 2, 2, 1", # for fun accumulate r1 (VL) into r2
244 "sv.bc/all 16, *0, -0x8", # branch, test CTR, reducing by VL
249 # SVSTATE - set vl and maxvl to 2, they get overridden with setvl
250 svstate
= SVP64State()
252 svstate
.maxvl
= 2 # MAXVL
253 print("SVSTATE", bin(svstate
.asint()))
255 sprs
= {'CTR': target
}
257 with
Program(lst
, bigendian
=False) as program
:
258 sim
= self
.run_tst_program(program
, svstate
=svstate
,
262 self
.assertEqual(sim
.spr('CTR'), SelectableInt(0, 64))
263 self
.assertEqual(sim
.gpr(2), SelectableInt(target
, 64))
264 # MAXVL repeatedly subtracted from VL (r1), last loop has remainder
265 self
.assertEqual(sim
.gpr(1), SelectableInt(target
% maxvl
, 64))
267 def norun_sv_add_cr(self
):
268 """>>> lst = ['sv.add. *1, *5, *9'
271 adds when Rc=1: TODO CRs higher up
272 * 1 = 5 + 9 => 0 = -1+1 CR0=0b100
273 * 2 = 6 + 10 => 0x3334 = 0x2223+0x1111 CR1=0b010
275 isa
= SVP64Asm(['sv.add. *1, *5, *9'
278 print("listing", lst
)
280 # initial values in GPR regfile
281 initial_regs
= [0] * 32
282 initial_regs
[9] = 0xffffffffffffffff
283 initial_regs
[10] = 0x1111
284 initial_regs
[5] = 0x1
285 initial_regs
[6] = 0x2223
286 # SVSTATE (in this case, VL=2)
287 svstate
= SVP64State()
289 svstate
.maxvl
= 2 # MAXVL
290 print("SVSTATE", bin(svstate
.asint()))
291 # copy before running
292 expected_regs
= deepcopy(initial_regs
)
293 expected_regs
[1] = initial_regs
[5] + initial_regs
[9] # 0x0
294 expected_regs
[2] = initial_regs
[6] + initial_regs
[10] # 0x3334
296 with
Program(lst
, bigendian
=False) as program
:
297 sim
= self
.run_tst_program(program
, initial_regs
, svstate
)
298 # XXX TODO, these need to move to higher range (offset)
299 cr0_idx
= SVP64CROffs
.CR0
300 cr1_idx
= SVP64CROffs
.CR1
301 CR0
= sim
.crl
[cr0_idx
].get_range().value
302 CR1
= sim
.crl
[cr1_idx
].get_range().value
305 self
._check
_regs
(sim
, expected_regs
)
306 self
.assertEqual(CR0
, SelectableInt(2, 4))
307 self
.assertEqual(CR1
, SelectableInt(4, 4))
309 def test_sv_branch_vertical_first(self
):
310 """this is a branch-vertical-first-loop demo which shows an early
311 branch from vertical-first loop based on the value of CR field bit.
316 "setvl 0, 0, %d, 1, 1, 1" % maxvl
, # VL = MAXVL = 2, vf=1
317 "sv.cmpi *cr0, 1, *10, 0x10", # compare reg val with immediate
318 "sv.bc 0, *2, 0x10", # jmp if CTR!=0 AND reg not equal to imm
319 "svstep. 27, 0, 1, 0",
320 "bc 4, 3, -0x14", # CR_BI=0, jump to start of loop (sv.cmpi)
321 "or 0, 0, 0", # jump to here if terminate VF loop early
328 # Two registers filled, but only the first one matters
332 sprs
= {'CTR': maxvl
}
334 with
Program(lst
, bigendian
=False) as program
:
335 sim
= self
.run_tst_program(program
,
340 self
.assertEqual(sim
.spr('CTR'), SelectableInt(1, 64))
342 def run_tst_program(self
, prog
, initial_regs
=None,
345 if initial_regs
is None:
346 initial_regs
= [0] * 32
347 simulator
= run_tst(prog
, initial_regs
, svstate
=svstate
,
348 initial_sprs
=initial_sprs
)
353 if __name__
== "__main__":