fecac44e51fe24f70bbc93838f144907c40ec034
1 from openpower
.insndb
.asm
import SVP64Asm
2 from openpower
.test
.common
import TestAccumulatorBase
, skip_case
3 from openpower
.endian
import bigendian
4 from openpower
.simulator
.program
import Program
5 from openpower
.decoder
.isa
.caller
import SVP64State
6 from openpower
.test
.state
import ExpectedState
7 from nmutil
.sim_util
import hash_256
9 from fractions
import Fraction
12 class MADDSUBRSTestCase(TestAccumulatorBase
):
13 def case_0_maddsubrs(self
):
14 isa
= SVP64Asm(["maddsubrs 1,10,14,11"])
17 initial_regs
= [0] * 32
18 initial_regs
[1] = 0x00000a71
19 initial_regs
[10] = 0x0000e6b8
20 initial_regs
[11] = 0x00002d41
22 e
= ExpectedState(pc
=4)
23 e
.intregs
[1] = 0x0000aa86
24 e
.intregs
[2] = 0xffffffffffff643e
25 e
.intregs
[10] = 0x0000e6b8
26 e
.intregs
[11] = 0x00002d41
27 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
29 def case_1_maddsubrs(self
):
30 isa
= SVP64Asm(["maddsubrs 1,10,0,11"])
33 initial_regs
= [0] * 32
34 initial_regs
[1] = 0x00000a71
35 initial_regs
[10] = 0x0000e6b8
36 initial_regs
[11] = 0x00002d41
38 e
= ExpectedState(pc
=4)
39 e
.intregs
[1] = 0x2aa17069
40 e
.intregs
[2] = 0xffffffffd90f96f9
41 e
.intregs
[10] = 0x0000e6b8
42 e
.intregs
[11] = 0x00002d41
43 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
45 def case_2_maddsubrs(self
):
46 isa
= SVP64Asm(["maddsubrs 1,10,2,11"])
49 initial_regs
= [0] * 32
50 initial_regs
[1] = 0x100000000
51 initial_regs
[10] = 0x000000003
52 initial_regs
[11] = 0x10000000
54 e
= ExpectedState(pc
=4)
55 e
.intregs
[1] = 0x40000000c000000
56 e
.intregs
[2] = 0x3fffffff4000000
57 e
.intregs
[10] = 0x00000003
58 e
.intregs
[11] = 0x10000000
59 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
61 def case_3_maddsubrs(self
):
62 isa
= SVP64Asm(["maddsubrs 1,10,16,11"])
65 initial_regs
= [0] * 32
66 initial_regs
[1] = 0x100000000
67 initial_regs
[10] = 0x000000003
68 initial_regs
[11] = 0x10000000
70 e
= ExpectedState(pc
=4)
71 e
.intregs
[1] = 0x100000003000
72 e
.intregs
[2] = 0x0fffffffd000
73 e
.intregs
[10] = 0x00000003
74 e
.intregs
[11] = 0x10000000
75 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
77 def case_4_maddsubrs(self
):
78 isa
= SVP64Asm(["maddsubrs 1,10,1,11"])
81 initial_regs
= [0] * 32
82 initial_regs
[1] = 0x100000000
83 initial_regs
[10] = 0x000000003
84 initial_regs
[11] = 0xff0000000
86 e
= ExpectedState(pc
=4)
87 e
.intregs
[1] = 0xf8000017e8000000
88 e
.intregs
[2] = 0xf7ffffe818000000
89 e
.intregs
[10] = 0x000000003
90 e
.intregs
[11] = 0xff0000000
91 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
93 def case_maddsubrs_16bit_s14(self
):
94 p
= Program(list(SVP64Asm([
95 "sv.maddsubrs/w=16 *10,*20,14,*30",
98 initial_regs
= [0] * 32
100 # use somewhat reasonable i16 values since we're working in
101 # 2.14-bit fixed-point
103 initial_regs
[10] = 0x1000_2000_3000_4000 # 0x0.4, 0x0.8, 0x0.c, 0x1.0
105 # 0x0.48d0, -0x0.0490, 0x0.d158, -0x0.48d4
106 initial_regs
[20] = 0x1234_fedc_3456_edcb
107 cospi_16_64
= 11585 # from libvpx -- 0x0.b504 ~ 0.70709 ~ cos(pi/4)
108 initial_regs
[30] = cospi_16_64
* 0x1_0001_0001_0001 # splat 4x
110 svstate
= SVP64State()
114 e
= ExpectedState(pc
=8, int_regs
=initial_regs
)
117 for i
in range(svstate
.vl
):
118 rt
= (initial_regs
[10] >> (i
* 16)) & 0xFFFF # extract element
119 rt
-= (rt
& 0x8000) << 1 # sign extend rt
120 ra
= (initial_regs
[20] >> (i
* 16)) & 0xFFFF
121 ra
-= (ra
& 0x8000) << 1 # sign extend ra
122 rb
= (initial_regs
[30] >> (i
* 16)) & 0xFFFF
123 rb
-= (rb
& 0x8000) << 1 # sign extend rb
126 # f64 is big enough to represent all relevant values exactly,
127 # so we can use float
128 rt
= math
.floor((s
* rb
) / (2 ** 14) + 0.5) # mul & round & shr
129 rs
= math
.floor((d
* rb
) / (2 ** 14) + 0.5)
130 e
.intregs
[10] |
= (rt
& 0xFFFF) << (16 * i
) # insert element
131 e
.intregs
[11] |
= (rs
& 0xFFFF) << (16 * i
)
133 # asserts so you can read the expected values
134 assert e
.intregs
[10] == 0x182f_15d2_46f2_2061
135 assert e
.intregs
[11] == 0xfe71_176f_fcef_3a21
137 self
.add_case(p
, initial_regs
, expected
=e
, initial_svstate
=svstate
)
139 def maddsubrs_many_helper(self
, width
, shift
, prog
, case_idx
):
140 # if {'width': width, 'shift': shift, 'case_idx': case_idx} \
141 # != {'width': 8, 'shift': 1, 'case_idx': 0}:
142 # return # for debugging
144 # make some reproducible random inputs
145 k
= f
"maddsubrs {width} {shift} {case_idx}"
146 gprs
[10] = hash_256(k
+ " r10") % 2**64
147 gprs
[20] = hash_256(k
+ " r20") % 2**64
148 gprs
[30] = hash_256(k
+ " r30") % 2**64
150 svstate
= SVP64State()
151 svstate
.vl
= 64 // width
# one full 64-bit register
152 svstate
.maxvl
= 64 // width
154 e
= ExpectedState(pc
=8, int_regs
=gprs
)
157 for i
in range(svstate
.vl
):
159 rt
= (gprs
[10] >> (i
* width
)) % 2 ** width
160 ra
= (gprs
[20] >> (i
* width
)) % 2 ** width
161 rb
= (gprs
[30] >> (i
* width
)) % 2 ** width
162 if rt
>= 2 ** (width
- 1):
163 rt
-= 2 ** width
# sign extend rt
164 if ra
>= 2 ** (width
- 1):
165 ra
-= 2 ** width
# sign extend ra
166 if rb
>= 2 ** (width
- 1):
167 rb
-= 2 ** width
# sign extend rb
170 factor
= Fraction(1, 2 ** shift
) # shr factor
171 round_up
= Fraction(1, 2)
173 rt
= math
.floor((s
* rb
) * factor
+ round_up
)
174 rs
= math
.floor((d
* rb
) * factor
+ round_up
)
176 e
.intregs
[10] |
= (rt
% 2 ** width
) << (width
* i
)
177 e
.intregs
[11] |
= (rs
% 2 ** width
) << (width
* i
)
180 width
=width
, shift
=shift
, case_idx
=case_idx
,
181 RT_in
=hex(gprs
[10]), RA_in
=hex(gprs
[20]), RB_in
=hex(gprs
[30]),
182 expected_RT
=hex(e
.intregs
[10]), expected_RS
=hex(e
.intregs
[11]),
184 self
.add_case(prog
, gprs
, expected
=e
, initial_svstate
=svstate
)
186 def case_maddsubrs_many(self
):
187 for width
in 8, 16, 32, 64:
188 shift_end
= min(32, width
)
189 for shift
in range(0, shift_end
, shift_end
// 8):
190 w
= "" if width
== 64 else f
"/w={width}"
191 prog
= Program(list(SVP64Asm([
192 f
"sv.maddsubrs{w} *10,*20,{shift},*30",
195 for case_idx
in range(25):
196 self
.maddsubrs_many_helper(width
, shift
, prog
, case_idx
)
198 def case_0_maddrs(self
):
199 isa
= SVP64Asm(["maddsubrs 1,10,0,11",
203 initial_regs
= [0] * 32
204 initial_regs
[1] = 0x00000a71
205 initial_regs
[10] = 0x0000e6b8
206 initial_regs
[11] = 0x00002d41
207 initial_regs
[12] = 0x00000d00
209 e
= ExpectedState(pc
=8)
210 e
.intregs
[1] = 0x3658c869
211 e
.intregs
[2] = 0xffffffffcd583ef9
212 e
.intregs
[10] = 0x0000e6b8
213 e
.intregs
[11] = 0x00002d41
214 e
.intregs
[12] = 0x00000d00
215 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
217 def case_1_maddrs(self
):
218 isa
= SVP64Asm(["maddsubrs 1,10,0,11",
219 "maddrs 1,10,14,12"])
222 initial_regs
= [0] * 32
223 initial_regs
[1] = 0x00000a71
224 initial_regs
[10] = 0x0000e6b8
225 initial_regs
[11] = 0x00002d41
226 initial_regs
[12] = 0x00000d00
228 e
= ExpectedState(pc
=8)
229 e
.intregs
[1] = 0x0000d963
230 e
.intregs
[2] = 0xffffffffffff3561
231 e
.intregs
[10] = 0x0000e6b8
232 e
.intregs
[11] = 0x00002d41
233 e
.intregs
[12] = 0x00000d00
234 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)