re-enable accidentally-disabled sv ld/st tests
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_svp64_ldst.py
1 from nmigen import Module, Signal
2 from nmigen.back.pysim 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_elementstride(self):
26 """>>> lst = ["addi 1, 0, 0x0010",
27 "addi 2, 0, 0x0008",
28 "addi 5, 0, 0x1234",
29 "addi 6, 0, 0x1235",
30 "sv.stw/els 5.v, 16(1)",
31 "sv.lwz/els 9.v, 16(1)"]
32
33 note: element stride mode is only enabled when RA is a scalar
34 and when the immediate is non-zero
35
36 element stride is computed as:
37 for i in range(VL):
38 EA = (RA|0) + EXTS(D) * i
39 """
40 lst = SVP64Asm(["addi 1, 0, 0x0010",
41 "addi 2, 0, 0x0008",
42 "addi 5, 0, 0x1234",
43 "addi 6, 0, 0x1235",
44 "sv.stw/els 5.v, 24(1)", # scalar r1 + 16 + 24*offs
45 "sv.lwz/els 9.v, 24(1)"]) # scalar r1 + 16 + 24*offs
46 lst = list(lst)
47
48 # SVSTATE (in this case, VL=2)
49 svstate = SVP64State()
50 svstate.vl[0:7] = 2 # VL
51 svstate.maxvl[0:7] = 2 # MAXVL
52 print ("SVSTATE", bin(svstate.spr.asint()))
53
54 with Program(lst, bigendian=False) as program:
55 sim = self.run_tst_program(program, svstate=svstate)
56 mem = sim.mem.dump(printout=False)
57 print (mem)
58 # contents of memory expected at:
59 # element 0: r1=0x10, D=24, => EA = 0x10+24*0 = 16 (0x10)
60 # element 1: r1=0x10, D=24, => EA = 0x10+24*1 = 40 (0x28)
61 # therefore, at address 0x10 ==> 0x1234
62 # therefore, at address 0x28 ==> 0x1235
63 expected_mem = [(16, 0x1234),
64 (40, 0x1235)]
65 self.assertEqual(mem, expected_mem)
66 print(sim.gpr(1))
67 self.assertEqual(sim.gpr(9), SelectableInt(0x1234, 64))
68 self.assertEqual(sim.gpr(10), SelectableInt(0x1235, 64))
69
70 def test_sv_load_store_unitstride(self):
71 """>>> lst = ["addi 1, 0, 0x0010",
72 "addi 2, 0, 0x0008",
73 "addi 5, 0, 0x1234",
74 "addi 6, 0, 0x1235",
75 "sv.stw 5.v, 8(1)",
76 "sv.lwz 9.v, 8(1)"]
77
78 note: unit stride mode is only enabled when RA is a scalar.
79
80 unit stride is computed as:
81 for i in range(VL):
82 EA = (RA|0) + EXTS(D) + LDSTsize * i
83 where for stw and lwz, LDSTsize is 4 because it is 32-bit words
84 """
85 lst = SVP64Asm(["addi 1, 0, 0x0010",
86 "addi 2, 0, 0x0008",
87 "addi 5, 0, 0x1234",
88 "addi 6, 0, 0x1235",
89 "sv.stw 5.v, 8(1)", # scalar r1 + 8 + wordlen*offs
90 "sv.lwz 9.v, 8(1)"]) # scalar r1 + 8 + wordlen*offs
91 lst = list(lst)
92
93 # SVSTATE (in this case, VL=2)
94 svstate = SVP64State()
95 svstate.vl[0:7] = 2 # VL
96 svstate.maxvl[0:7] = 2 # MAXVL
97 print ("SVSTATE", bin(svstate.spr.asint()))
98
99 with Program(lst, bigendian=False) as program:
100 sim = self.run_tst_program(program, svstate=svstate)
101 mem = sim.mem.dump(printout=False)
102 print (mem)
103 # contents of memory expected at:
104 # element 0: r1=0x10, D=8, wordlen=4 => EA = 0x10+8+4*0 = 0x24
105 # element 1: r1=0x10, D=8, wordlen=4 => EA = 0x10+8+4*8 = 0x28
106 # therefore, at address 0x24 ==> 0x1234
107 # therefore, at address 0x28 ==> 0x1235
108 self.assertEqual(mem, [(24, 0x123500001234)])
109 print(sim.gpr(1))
110 self.assertEqual(sim.gpr(9), SelectableInt(0x1234, 64))
111 self.assertEqual(sim.gpr(10), SelectableInt(0x1235, 64))
112
113 def test_sv_load_store_bitreverse(self):
114 """>>> lst = ["addi 1, 0, 0x0010",
115 "addi 2, 0, 0x0004",
116 "addi 3, 0, 0x0002",
117 "addi 5, 0, 0x101",
118 "addi 6, 0, 0x202",
119 "addi 7, 0, 0x303",
120 "addi 8, 0, 0x404",
121 "sv.stw 5.v, 0(1)",
122 "sv.lwzbr 9.v, 4(1), 2"]
123
124 note: bitreverse mode is... odd. it's the butterfly generator
125 from Cooley-Tukey FFT:
126 https://en.wikipedia.org/wiki/Cooley%E2%80%93Tukey_FFT_algorithm#Data_reordering,_bit_reversal,_and_in-place_algorithms
127
128 bitreverse LD is computed as:
129 for i in range(VL):
130 EA = (RA|0) + (EXTS(D) * LDSTsize * bitreverse(i, VL)) << RC
131
132 bitreversal of 0 1 2 3 in binary 0b00 0b01 0b10 0b11
133 produces 0 2 1 3 in binary 0b00 0b10 0b01 0b11
134
135 and thus creates the butterfly needed for one iteration of FFT.
136 the RC (shift) is to be able to offset the LDs by Radix-2 spans
137 """
138 lst = SVP64Asm(["addi 1, 0, 0x0010",
139 "addi 2, 0, 0x0000",
140 "addi 5, 0, 0x101",
141 "addi 6, 0, 0x202",
142 "addi 7, 0, 0x303",
143 "addi 8, 0, 0x404",
144 "sv.stw 5.v, 0(1)", # scalar r1 + 0 + wordlen*offs
145 "sv.lwzbr 9.v, 4(1), 2"]) # bit-reversed
146 lst = list(lst)
147
148 # SVSTATE (in this case, VL=4)
149 svstate = SVP64State()
150 svstate.vl[0:7] = 4 # VL
151 svstate.maxvl[0:7] = 4 # MAXVL
152 print ("SVSTATE", bin(svstate.spr.asint()))
153
154 with Program(lst, bigendian=False) as program:
155 sim = self.run_tst_program(program, svstate=svstate)
156 mem = sim.mem.dump(printout=False)
157 print (mem)
158
159 self.assertEqual(mem, [(16, 0x020200000101),
160 (24, 0x040400000303)])
161 print(sim.gpr(1))
162 # from STs
163 self.assertEqual(sim.gpr(5), SelectableInt(0x101, 64))
164 self.assertEqual(sim.gpr(6), SelectableInt(0x202, 64))
165 self.assertEqual(sim.gpr(7), SelectableInt(0x303, 64))
166 self.assertEqual(sim.gpr(8), SelectableInt(0x404, 64))
167 # r1=0x10, RC=0, offs=4: contents of memory expected at:
168 # element 0: EA = r1 + bitrev(0b00)*4 => 0x10 + 0b00*4 => 0x10
169 # element 1: EA = r1 + bitrev(0b01)*4 => 0x10 + 0b10*4 => 0x18
170 # element 2: EA = r1 + bitrev(0b10)*4 => 0x10 + 0b01*4 => 0x14
171 # element 3: EA = r1 + bitrev(0b11)*4 => 0x10 + 0b10*4 => 0x1c
172 # therefore loaded from (bit-reversed indexing):
173 # r9 => mem[0x10] which was stored from r5
174 # r10 => mem[0x18] which was stored from r6
175 # r11 => mem[0x18] which was stored from r7
176 # r12 => mem[0x1c] which was stored from r8
177 self.assertEqual(sim.gpr(9), SelectableInt(0x101, 64))
178 self.assertEqual(sim.gpr(10), SelectableInt(0x303, 64))
179 self.assertEqual(sim.gpr(11), SelectableInt(0x202, 64))
180 self.assertEqual(sim.gpr(12), SelectableInt(0x404, 64))
181
182 def run_tst_program(self, prog, initial_regs=None,
183 svstate=None):
184 if initial_regs is None:
185 initial_regs = [0] * 32
186 simulator = run_tst(prog, initial_regs, svstate=svstate)
187 simulator.gpr.dump()
188 return simulator
189
190
191 if __name__ == "__main__":
192 unittest.main()