bfc7a5b6e84e7ddbbfd4e9ab8de258b4c62e7434
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_svstate.py
1 """SVP64 unit test for doing strange things to SVSTATE, manually.
2 """
3 from nmigen import Module, Signal
4 from nmigen.sim import Simulator, Delay, Settle
5 from nmutil.formaltest import FHDLTestCase
6 import unittest
7 from openpower.decoder.isa.caller import ISACaller
8 from openpower.decoder.power_decoder import (create_pdecode)
9 from openpower.decoder.power_decoder2 import (PowerDecode2)
10 from openpower.simulator.program import Program
11 from openpower.decoder.isa.caller import ISACaller, SVP64State, CRFields
12 from openpower.decoder.selectable_int import SelectableInt
13 from openpower.decoder.orderedset import OrderedSet
14 from openpower.decoder.isa.all import ISA
15 from openpower.decoder.isa.test_caller import Register, run_tst
16 from openpower.sv.trans.svp64 import SVP64Asm
17 from openpower.consts import SVP64CROffs
18 from copy import deepcopy
19
20
21 class SVSTATETestCase(FHDLTestCase):
22
23 def _check_regs(self, sim, expected):
24 print ("GPR")
25 sim.gpr.dump()
26 for i in range(32):
27 self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64))
28
29 def test_sv_add(self):
30 """sets VL=2 (via SVSTATE) with a manual srcstep/dststep,
31 then does a scalar-result add. the result should be:
32
33 add 1, 6, 10
34
35 because whilst the Vector instruction was moved on by srcstep,
36 the Scalar one is NOT moved on.
37 """
38 isa = SVP64Asm(['sv.add 1, *5, *9'
39 ])
40 lst = list(isa)
41 print ("listing", lst)
42
43 # initial values in GPR regfile
44 initial_regs = [0] * 32
45 initial_regs[9] = 0x1234
46 initial_regs[10] = 0x1111
47 initial_regs[5] = 0x4321
48 initial_regs[6] = 0x2223
49
50 # SVSTATE (in this case, VL=3, and src/dststep set ALREADY to 1)
51 svstate = SVP64State()
52 svstate.vl = 2 # VL
53 svstate.maxvl = 2 # MAXVL
54 svstate.srcstep = 1 # srcstep
55 svstate.dststep = 1 # srcstep
56 print ("SVSTATE", bin(svstate.asint()))
57
58 # copy before running
59 expected_regs = deepcopy(initial_regs)
60 expected_regs[1] = 0x3334
61
62 with Program(lst, bigendian=False) as program:
63 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
64 self._check_regs(sim, expected_regs)
65
66 def test_svstep_add_1(self):
67 """tests svstep with an add, using scalar adds, when it reaches VL
68 lst = SVP64Asm(["setvl 0, 0, 2, 1, 1, 1",
69 'sv.add 1, *5, *9',
70 'sv.addi *12, 1, 1',
71 "svstep. 0, 1, 0",
72 'sv.add 1, *5, *9',
73 'sv.addi *12, 1, 1',
74 "svstep. 0, 1, 0",
75 ])
76
77 sequence is as follows:
78
79 * setvl sets VL=2 but also "Vertical First" mode.
80 this sets SVSTATE[SVF].
81 * first add, which has srcstep/dststep = 0, does add 1,5,9
82 * first addi, which has srcstep/dststep = 0, does addi 12, 1, #1
83 * svstep EXPLICITLY walks srcstep/dststep to next element
84 * second add, which now has srcstep/dststep = 1, does add 1,6,10
85 (because RT is a *SCALAR*)
86 * second addi, which has srcstep/dststep = 1, does addi 13, 1, #1
87 * svstep EXPLICITLY walks srcstep/dststep to next element,
88 which now equals VL. srcstep and dststep are both set to
89 zero. CR0.SO is set to 1 because
90 it is the end of the looping.
91
92 the first add will write 0x5555 into r1, then the vector-addi
93 will add 1 to that and store the result in r12 (0x5556)
94
95 the second add will write 0x3334 into the temp r1, this *stays* there
96 obviously, and the second vector-addi will add 1 to the *new* r1 and
97 store the result in r13 (0x3335).
98
99 """
100 lst = SVP64Asm(["setvl 0, 0, 2, 1, 1, 1",
101 'sv.add 1, *5, *9', # scalar dest (into r1)
102 'sv.addi *12, 1, 1', # scalar src (from r1)
103 "svstep. 0, 1, 0", # svstep
104 'sv.add 1, *5, *9', # again, scalar dest
105 'sv.addi *12, 1, 1', # but vector dest
106 "svstep. 0, 1, 0", # svstep (end: sets CR0.SO)
107 ])
108 lst = list(lst)
109
110 # SVSTATE (in this case, VL=2)
111 svstate = SVP64State()
112 svstate.vl = 2 # VL
113 svstate.maxvl = 2 # MAXVL
114 print ("SVSTATE", bin(svstate.asint()))
115
116 # initial values in GPR regfile
117 initial_regs = [0] * 32
118 initial_regs[9] = 0x1234
119 initial_regs[10] = 0x1111
120 initial_regs[5] = 0x4321
121 initial_regs[6] = 0x2223
122
123 # copy before running
124 expected_regs = deepcopy(initial_regs)
125 expected_regs[1] = 0x3334 # last temporary
126 expected_regs[12] = 0x5556
127 expected_regs[13] = 0x3335
128
129 with Program(lst, bigendian=False) as program:
130 sim = self.run_tst_program(program, initial_regs, svstate=svstate)
131 print ("SVSTATE after", bin(sim.svstate.asint()))
132 print (" vl", bin(sim.svstate.vl))
133 print (" mvl", bin(sim.svstate.maxvl))
134 print (" srcstep", bin(sim.svstate.srcstep))
135 print (" dststep", bin(sim.svstate.dststep))
136 self.assertEqual(sim.svstate.vl, 2)
137 self.assertEqual(sim.svstate.maxvl, 2)
138 self.assertEqual(sim.svstate.srcstep, 0)
139 self.assertEqual(sim.svstate.dststep, 0)
140 # when end reached, vertical mode is exited
141 print(" msr", bin(sim.msr.value)) # should be zero
142 self.assertEqual(sim.msr, SelectableInt(0<<(63-6), 64))
143 CR0 = sim.crl[0]
144 print(" CR0", bin(CR0.get_range().value))
145 self.assertEqual(CR0[CRFields.EQ], 0)
146 self.assertEqual(CR0[CRFields.LT], 0)
147 self.assertEqual(CR0[CRFields.GT], 0)
148 self.assertEqual(CR0[CRFields.SO], 1)
149
150 # check registers as expected
151 self._check_regs(sim, expected_regs)
152
153 def run_tst_program(self, prog, initial_regs=None,
154 svstate=None):
155 if initial_regs is None:
156 initial_regs = [0] * 32
157 simulator = run_tst(prog, initial_regs, svstate=svstate)
158 simulator.gpr.dump()
159 return simulator
160
161
162 if __name__ == "__main__":
163 unittest.main()
164