21223be3197959c58c735023c8d77a76699837ac
[openpower-isa.git] / src / openpower / test / bigint / bigint_cases.py
1 from openpower.test.common import TestAccumulatorBase, skip_case
2 from openpower.sv.trans.svp64 import SVP64Asm
3 from openpower.test.state import ExpectedState
4 from openpower.simulator.program import Program
5 from openpower.decoder.isa.caller import SVP64State
6
7 _SHIFT_TEST_RANGE = list(range(-64, 128, 16)) + [1, 63]
8
9
10 class BigIntCases(TestAccumulatorBase):
11 def case_maddedu(self):
12 lst = list(SVP64Asm(["maddedu 3,5,6,7"]))
13 gprs = [0] * 32
14 gprs[5] = 0x123456789ABCDEF
15 gprs[6] = 0xFEDCBA9876543210
16 gprs[7] = 0x02468ACE13579BDF
17 e = ExpectedState(pc=4, int_regs=gprs)
18 e.intregs[3] = (gprs[5] * gprs[6] + gprs[7]) % 2 ** 64
19 e.intregs[7] = (gprs[5] * gprs[6] + gprs[7]) >> 64
20 self.add_case(Program(lst, False), gprs, expected=e)
21
22 def case_divmod2du(self):
23 lst = list(SVP64Asm(["divmod2du 3,5,6,7"]))
24 gprs = [0] * 32
25 gprs[5] = 0x123456789ABCDEF
26 gprs[6] = 0xFEDCBA9876543210
27 gprs[7] = 0x02468ACE13579BDF
28 e = ExpectedState(pc=4, int_regs=gprs)
29 v = gprs[5] | (gprs[7] << 64)
30 e.intregs[3] = v // gprs[6]
31 e.intregs[7] = v % gprs[6]
32 self.add_case(Program(lst, False), gprs, expected=e)
33
34 # FIXME: test more divmod2du special cases
35
36 def case_dsld0(self):
37 prog = Program(list(SVP64Asm(["dsld 3,4,5,6"])), False)
38 for sh in _SHIFT_TEST_RANGE:
39 with self.subTest(sh=sh):
40 gprs = [0] * 32
41 gprs[6] = 0x123456789ABCDEF
42 gprs[4] = 0xFEDCBA9876543210
43 gprs[5] = sh % 2 ** 64
44 e = ExpectedState(pc=4, int_regs=gprs)
45 v = gprs[4]
46 v <<= sh % 64
47 mask = (1<<(sh%64))-1
48 v |= gprs[6] & mask
49 e.intregs[3] = v % 2 ** 64
50 e.intregs[6] = (v >> 64) % 2 ** 64
51 self.add_case(prog, gprs, expected=e)
52
53 def case_dsrd0(self):
54 prog = Program(list(SVP64Asm(["dsrd 3,4,5,3"])), False)
55 for sh in _SHIFT_TEST_RANGE:
56 with self.subTest(sh=sh):
57 gprs = [0] * 32
58 gprs[3] = 0x123456789ABCDEF
59 gprs[4] = 0xFEDCBA9876543210
60 gprs[5] = sh % 2 ** 64
61 e = ExpectedState(pc=4, int_regs=gprs)
62 v = (gprs[3] << 64) | gprs[4]
63 v >>= sh % 64
64 e.intregs[3] = v % 2 ** 64
65 self.add_case(prog, gprs, expected=e)
66
67 def case_dsrd1(self):
68 prog = Program(list(SVP64Asm(["dsrd 3,3,5,4"])), False)
69 for sh in _SHIFT_TEST_RANGE:
70 with self.subTest(sh=sh):
71 gprs = [0] * 32
72 gprs[3] = 0x123456789ABCDEF
73 gprs[4] = 0xFEDCBA9876543210
74 gprs[5] = sh % 2 ** 64
75 e = ExpectedState(pc=4, int_regs=gprs)
76 v = (gprs[4] << 64) | gprs[3]
77 v >>= sh % 64
78 e.intregs[3] = v % 2 ** 64
79 self.add_case(prog, gprs, expected=e)
80
81 def case_dsrd2(self):
82 prog = Program(list(SVP64Asm(["dsrd 3,5,3,4"])), False)
83 for sh in _SHIFT_TEST_RANGE:
84 with self.subTest(sh=sh):
85 gprs = [0] * 32
86 gprs[3] = sh % 2 ** 64
87 gprs[4] = 0xFEDCBA9876543210
88 gprs[5] = 0x02468ACE13579BDF
89 e = ExpectedState(pc=4, int_regs=gprs)
90 v = (gprs[4] << 64) | gprs[5]
91 v >>= sh % 64
92 e.intregs[3] = v % 2 ** 64
93 self.add_case(prog, gprs, expected=e)
94
95
96 class SVP64BigIntCases(TestAccumulatorBase):
97 def case_sv_bigint_add(self):
98 """performs a carry-rollover-vector-add aka "big integer vector add"
99 this is remarkably simple, each sv.adde uses and produces a CA which
100 goes into the next sv.adde. arbitrary size is possible (1024+) as
101 is looping using the CA bit from one sv.adde on another batch to do
102 unlimited-size biginteger add.
103
104 r19/r18: 0x0000_0000_0000_0001 0xffff_ffff_ffff_ffff +
105 r21/r20: 0x8000_0000_0000_0000 0x0000_0000_0000_0001 =
106 r17/r16: 0x8000_0000_0000_0002 0x0000_0000_0000_0000
107 """
108 prog = Program(list(SVP64Asm(["sv.adde *16, *18, *20"])), False)
109 gprs = [0] * 32
110 gprs[18] = 0xffff_ffff_ffff_ffff
111 gprs[19] = 0x0000_0000_0000_0001
112 gprs[20] = 0x0000_0000_0000_0001
113 gprs[21] = 0x8000_0000_0000_0000
114 svstate = SVP64State()
115 svstate.vl = 2
116 svstate.maxvl = 2
117 e = ExpectedState(pc=8, int_regs=gprs)
118 e.intregs[16] = 0x0000_0000_0000_0000
119 e.intregs[17] = 0x8000_0000_0000_0002
120 self.add_case(prog, gprs, expected=e, initial_svstate=svstate)
121
122 def case_sv_bigint_shift_right_by_scalar(self):
123 """performs a bigint shift-right by scalar.
124
125 r18 r17 r16 r3
126 0x0000_0000_5000_0002 0x8000_8000_8000_8001 0xffff_ffff_ffff_ffff >> 4
127 0x0000_0000_0500_0000 0x2800_0800_0800_0800 0x1fff_ffff_ffff_ffff
128 """
129 prog = Program(list(SVP64Asm(["sv.dsrd *16,*17,3,1"])), False)
130 gprs = [0] * 32
131 gprs[16] = 0xffff_ffff_ffff_ffff
132 gprs[17] = 0x8000_8000_8000_8001
133 gprs[18] = 0x0000_0000_5000_0002
134 gprs[3] = 4
135 svstate = SVP64State()
136 svstate.vl = 3
137 svstate.maxvl = 3
138 e = ExpectedState(pc=8, int_regs=gprs)
139 e.intregs[16] = 0x1fff_ffff_ffff_ffff
140 e.intregs[17] = 0x2800_0800_0800_0800
141 e.intregs[18] = 0x0000_0000_0500_0000
142 self.add_case(prog, gprs, expected=e, initial_svstate=svstate)
143
144 def case_sv_bigint_shift_left_by_scalar(self):
145 """performs a bigint shift-left by scalar.
146
147 because the result is moved down by one register there is no need
148 for reverse-gear.
149
150 r18 is *not* modified (contains its original value).
151 r18 r17 r16 r3
152 0x0000_0000_0001_0002 0x3fff_ffff_ffff_ffff 0x4000_0000_0000_0001 << 4
153 r17 r16 r15
154 0x0000_0000_0010_0023 0xffff_ffff_ffff_fff4 0x0000_0000_0000_0010
155 """
156 prog = Program(list(SVP64Asm(["sv.dsld *15,*16,3,1"])), False)
157 gprs = [0] * 32
158 gprs[15] = 0
159 gprs[16] = 0x4000_0000_0000_0001
160 gprs[17] = 0x3fff_ffff_ffff_ffff
161 gprs[18] = 0x0000_0000_0001_0002
162 gprs[3] = 4
163 svstate = SVP64State()
164 svstate.vl = 3
165 svstate.maxvl = 3
166 e = ExpectedState(pc=8, int_regs=gprs)
167 e.intregs[15] = 0x0000_0000_0000_0010
168 e.intregs[16] = 0xffff_ffff_ffff_fff4
169 e.intregs[17] = 0x0000_0000_0010_0023
170 self.add_case(prog, gprs, expected=e, initial_svstate=svstate)
171
172 def case_sv_bigint_mul_by_scalar(self):
173 """performs a carry-rollover-vector-mul-with-add with a scalar,
174 using "RC" as a 64-bit carry in/out. matched with the
175 sv.divmod2du below
176
177 r18 r17 r16
178 0x1234_0000_5678_0000 0x9ABC_0000_DEF0_0000 0x1357_0000_9BDF_0000 *
179 r3 (scalar factor) 0x1_0001 +
180 r4 (carry in) 0xFEDC =
181 r18 r17 r16
182 0x1234_5678_5678_9ABC 0x9ABC_DEF0_DEF0_1357 0x1357_9BDF_9BDF_FEDC
183 r4 (carry out) 0x1234
184 """
185 prog = Program(list(SVP64Asm(["sv.maddedu *16,*16,3,4"])), False)
186 gprs = [0] * 32
187 gprs[16] = 0x1357_0000_9BDF_0000 # vector...
188 gprs[17] = 0x9ABC_0000_DEF0_0000 # ...
189 gprs[18] = 0x1234_0000_5678_0000 # ... input
190 gprs[3] = 0x1_0001 # scalar multiplier
191 gprs[4] = 0xFEDC # 64-bit carry-in
192 svstate = SVP64State()
193 svstate.vl = 3
194 svstate.maxvl = 3
195 e = ExpectedState(pc=8, int_regs=gprs)
196 e.intregs[16] = 0x1357_9BDF_9BDF_FEDC # vector...
197 e.intregs[17] = 0x9ABC_DEF0_DEF0_1357 # ...
198 e.intregs[18] = 0x1234_5678_5678_9ABC # ... result
199 e.intregs[4] = 0x1234 # 64-bit carry-out
200 self.add_case(prog, gprs, expected=e, initial_svstate=svstate)
201
202 def case_sv_bigint_scalar_maddedu(self):
203 prog = Program(list(SVP64Asm(["sv.maddedu 6,5,3,4"])), False)
204 gprs = [0] * 32
205 gprs[5] = 0x1357_0000_9BDF_0000 # scalar input
206 gprs[3] = 0x1_0001 # scalar multiplier
207 gprs[4] = 0xFEDC # 64-bit carry-in
208 svstate = SVP64State()
209 svstate.vl = 16 # detect writing to RT+MAXVL or RT+1 rather than RC
210 svstate.maxvl = 16
211 e = ExpectedState(pc=8, int_regs=gprs)
212 e.intregs[6] = 0x1357_9BDF_9BDF_FEDC # scalar output
213 e.intregs[4] = 0x1357 # 64-bit carry-out
214 self.add_case(prog, gprs, expected=e, initial_svstate=svstate)
215
216 def case_sv_bigint_div_by_scalar(self):
217 """performs a carry-rollover-vector-divmod with a scalar,
218 using "RC" as a 64-bit carry. matched with the sv.maddedu
219 above it is effectively the scalar-vector inverse
220
221 r18 r17 r16
222 0x1234_5678_5678_9ABC 0x9ABC_DEF0_DEF0_1357 0x1357_9BDF_9BDF_FEDC /
223 r3 (scalar factor) 0x1_0001 +
224 r4 (carry in at top-end) 0x1234 << 192 =
225 r18 r17 r16
226 0x1234_0000_5678_0000 0x9ABC_0000_DEF0_0000 0x1357_0000_9BDF_0000 *
227 r4 (carry out i.e. scalar remainder) 0xFEDC
228 """
229 prog = Program(list(SVP64Asm(["sv.divmod2du/mrr *16,*16,3,4"])), False)
230 gprs = [0] * 32
231 gprs[16] = 0x1357_9BDF_9BDF_FEDC # vector...
232 gprs[17] = 0x9ABC_DEF0_DEF0_1357 # ...
233 gprs[18] = 0x1234_5678_5678_9ABC # ... input
234 gprs[3] = 0x1_0001 # scalar multiplier
235 gprs[4] = 0x1234 # 64-bit carry-in
236 svstate = SVP64State()
237 svstate.vl = 3
238 svstate.maxvl = 3
239 e = ExpectedState(pc=8, int_regs=gprs)
240 e.intregs[16] = 0x1357_0000_9BDF_0000 # vector...
241 e.intregs[17] = 0x9ABC_0000_DEF0_0000 # ...
242 e.intregs[18] = 0x1234_0000_5678_0000 # ... result
243 e.intregs[4] = 0xFEDC # 64-bit carry-out
244 self.add_case(prog, gprs, expected=e, initial_svstate=svstate)