6f6f6deab31c6c96f3e81cd0b408862185181311
[openpower-isa.git] / src / openpower / decoder / isa / test_caller_svp64_bigint.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, CRFields
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 class DecoderTestCase(FHDLTestCase):
19
20 def _check_regs(self, sim, expected):
21 for i in range(32):
22 self.assertEqual(sim.gpr(i), SelectableInt(expected[i], 64),
23 "reg %d expected %x got %x" % \
24 (i, sim.gpr(i).value, expected[i]))
25
26 def test_sv_bigint_add(self):
27 """performs a carry-rollover-vector-add aka "big integer vector add"
28 this is remarkably simple, each sv.adde uses and produces a CA which
29 goes into the next sv.adde. arbitrary size is possible (1024+) as
30 is looping using the CA bit from one sv.adde on another batch to do
31 unlimited-size biginteger add.
32
33 r3/r2: 0x0000_0000_0000_0001 0xffff_ffff_ffff_ffff +
34 r5/r4: 0x8000_0000_0000_0000 0x0000_0000_0000_0001 =
35 r1/r0: 0x8000_0000_0000_0002 0x0000_0000_0000_0000
36 """
37 isa = SVP64Asm(['sv.adde *0, *2, *4'
38 ])
39 lst = list(isa)
40 print ("listing", lst)
41
42 # initial values in GPR regfile
43 initial_regs = [0] * 32
44 initial_regs[2] = 0xffff_ffff_ffff_ffff # lo dword A
45 initial_regs[3] = 0x0000_0000_0000_0001 # hi dword A
46 initial_regs[4] = 0x0000_0000_0000_0001 # lo dword B
47 initial_regs[5] = 0x8000_0000_0000_0000 # hi dword B
48 # SVSTATE (in this case, VL=2)
49 svstate = SVP64State()
50 svstate.vl = 2 # VL
51 svstate.maxvl = 2 # MAXVL
52 print ("SVSTATE", bin(svstate.asint()))
53 # copy before running
54 expected_regs = deepcopy(initial_regs)
55 expected_regs[0] = 0x0 # rollover to zero, carry
56 expected_regs[1] = 0x8000_0000_0000_0002 # carry rolled-over
57
58 with Program(lst, bigendian=False) as program:
59 sim = self.run_tst_program(program, initial_regs, svstate)
60 self._check_regs(sim, expected_regs)
61
62 def test_sv_bigint_scalar_shiftright(self):
63 """performs a scalar-to-vector right-shift.
64
65 r3 r2 r1 r4
66 0x0000_0000_0000_0002 0x8000_8000_8000_8001 0xffff_ffff_ffff_ffff >> 4
67 0x0000_0000_0000_0002 0x2800_0800_0800_0800 0x1fff_ffff_ffff_ffff
68 """
69 isa = SVP64Asm(['sv.dsrd *0,*1,4,1'
70 ])
71 lst = list(isa)
72 print ("listing", lst)
73
74 # initial values in GPR regfile
75 initial_regs = [0] * 32
76 initial_regs[0] = 0xffff_ffff_ffff_ffff # lo dword A
77 initial_regs[1] = 0x8000_8000_8000_8001 # mid dword A
78 initial_regs[2] = 0x0000_0000_0000_0002 # hi dword A
79 initial_regs[4] = 0x0000_0000_0000_0004 # shift amount (a nibble)
80 # SVSTATE (in this case, VL=2)
81 svstate = SVP64State()
82 svstate.vl = 2 # VL
83 svstate.maxvl = 2 # MAXVL
84 print ("SVSTATE", bin(svstate.asint()))
85 # copy before running
86 expected_regs = deepcopy(initial_regs)
87 expected_regs[0] = 0x1fff_ffff_ffff_ffff # MSB nibble gets LSB
88 expected_regs[1] = 0x2800_0800_0800_0800 # hi dword A
89
90 with Program(lst, bigendian=False) as program:
91 sim = self.run_tst_program(program, initial_regs, svstate)
92 self._check_regs(sim, expected_regs)
93
94 def test_sv_bigint_scalar_shiftleft(self):
95 """performs a scalar-to-vector left-shift: because the result is moved
96 down by one scalar (RT=0 not 1) there is no need for reverse-gear.
97 r2 is *not* modified (contains its original value).
98 r2 r1 r0 r4
99 0x0000_0000_0001_0002 0x3fff_ffff_ffff_ffff 0x4000_0000_0000_0001 << 4
100 0x0000_0000_0001_0002 0x0000_0000_0010_0023 0xffff_ffff_ffff_fff4
101 """
102 isa = SVP64Asm(['sv.dsld *0,*1,4,1'
103 ])
104 lst = list(isa)
105 print ("listing", lst)
106
107 # initial values in GPR regfile
108 initial_regs = [0] * 32
109 initial_regs[0] = 0x4000_0000_0000_0001 # lo dword A
110 initial_regs[1] = 0x3fff_ffff_ffff_ffff # mid dword A
111 initial_regs[2] = 0x0000_0000_0001_0002 # hi dword A
112 initial_regs[4] = 0x0000_0000_0000_0004 # shift amount (a nibble)
113 # SVSTATE (in this case, VL=2)
114 svstate = SVP64State()
115 svstate.vl = 2 # VL
116 svstate.maxvl = 2 # MAXVL
117 print ("SVSTATE", bin(svstate.asint()))
118 # copy before running
119 expected_regs = deepcopy(initial_regs)
120 expected_regs[0] = 0xffff_ffff_ffff_fff4 # MSB nibble gets LSB
121 expected_regs[1] = 0x0000_0000_0010_0023 # hi dword A
122
123 with Program(lst, bigendian=False) as program:
124 sim = self.run_tst_program(program, initial_regs, svstate)
125 self._check_regs(sim, expected_regs)
126
127 def test_sv_bigint_mul(self):
128 """performs a carry-rollover-vector-mul-with-add with a scalar,
129 using "RC" as a 64-bit carry
130
131 r1 r0
132 0xffff_ffff_ffff_ffff 0xffff_ffff_ffff_ffff *
133 r4 (scalar) 0xffff_ffff_ffff_fffe +
134 r10 (scalar-add-in) 0x0000_0000_0000_0100 +
135
136 0xffff_ffff_ffff_fffd 0xffff_ffff_ffff_ffff 0x0000_0000_0000_0102
137 r10 (RC, MSB) r9 r8
138 """
139 isa = SVP64Asm(['sv.maddedu *8, *0, 4, 10'
140 ])
141 lst = list(isa)
142 print ("listing", lst)
143
144 # initial values in GPR regfile
145 initial_regs = [0] * 32
146 initial_regs[0] = 0xffff_ffff_ffff_ffff # lo dword of Vector A
147 initial_regs[1] = 0xffff_ffff_ffff_ffff # hi dword of Vector A
148 initial_regs[4] = 0xffff_ffff_ffff_fffe # scalar B
149 initial_regs[10] = 0x0000_0000_0000_0100 # RC-input
150 # SVSTATE (in this case, VL=2)
151 svstate = SVP64State()
152 svstate.vl = 2 # VL
153 svstate.maxvl = 3 # MAXVL
154 print ("SVSTATE", bin(svstate.asint()))
155 # copy before running
156 expected_regs = deepcopy(initial_regs)
157 # XXX the result is *three*-dword-long. RC, the carry roll-over,
158 # is a *legitimate* (valid) part of the result as it contains the
159 # hi-64-bit of the last multiply.
160 expected_regs[8] = 0x0000_0000_0000_0102 # least dword
161 expected_regs[9] = 0xffff_ffff_ffff_ffff # next dword
162 expected_regs[10] = 0xffff_ffff_ffff_fffd # carry roll-over, top dword
163
164 with Program(lst, bigendian=False) as program:
165 sim = self.run_tst_program(program, initial_regs, svstate)
166 self._check_regs(sim, expected_regs)
167
168 def run_tst_program(self, prog, initial_regs=None,
169 svstate=None,
170 initial_cr=0):
171 if initial_regs is None:
172 initial_regs = [0] * 32
173 simulator = run_tst(prog, initial_regs, svstate=svstate,
174 initial_cr=initial_cr)
175 simulator.gpr.dump()
176 return simulator
177
178
179 if __name__ == "__main__":
180 unittest.main()