6faba490c155db6874a73a444705b20e6612b1e5
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
.test
.state
import ExpectedState
6 from nmutil
.sim_util
import hash_256
7 from openpower
.decoder
.isa
.caller
import SVP64State
, CRFields
8 from openpower
.util
import log
16 b
= (ra
>> (63-k
*8-j
)) & 1
17 result |
= b
<< (63-j
*8-k
)
21 def crfbinlog(bf
, bfa
, bfb
, mask
):
23 expected
= bf
&~mask
# start at BF, mask overwrites masked bits only
24 checks
= (bfa
, bf
) # LUT positions 1<<0=bfa 1<<1=bf
27 for j
, check
in enumerate(checks
):
30 maskbit
= (mask
>> i
) & 0b1
31 if (lut
& (1<<lut_index
)) and maskbit
:
36 def ternlogi(rc
, rt
, ra
, rb
, imm
):
46 if imm
& 2 ** lut_index
:
51 def crternlogi(bt
, ba
, bb
, imm
):
53 checks
= (bb
, ba
, bt
) # LUT positions 1<<0=bb 1<<1=ba 1<<2=bt
55 for j
, check
in enumerate(checks
):
58 if imm
& (1<<lut_index
):
63 def crfternlogi(bf
, bfa
, bfb
, imm
, mask
):
64 expected
= bf
&~mask
# start at BF, mask overwrites masked bits only
65 checks
= (bfb
, bfa
, bf
) # LUT positions 1<<0=bfb 1<<1=bfa 1<<2=bf
68 for j
, check
in enumerate(checks
):
71 maskbit
= (mask
>> i
) & 0b1
72 if (imm
& (1<<lut_index
)) and maskbit
:
77 class BitManipTestCase(TestAccumulatorBase
):
80 lst
= list(SVP64Asm(lst
, bigendian
))
81 initial_regs
= [0] * 32
82 initial_regs
[1] = 0x9231_5897_2083_ffff
83 e
= ExpectedState(pc
=4)
84 e
.intregs
[0] = bmatflip(initial_regs
[1])
85 e
.intregs
[1] = initial_regs
[1]
86 log("case_gbbd", bin(initial_regs
[1]), bin(e
.intregs
[0]))
87 log("hex", hex(initial_regs
[1]), hex(e
.intregs
[0]))
89 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
91 def do_case_crternlogi(self
, bt
, ba
, bb
, imm
):
92 lst
= ["crternlogi 0,4,8,%d" % imm
]
93 # set up CR to match bt bit 0, ba bit 4, bb bit 8, in MSB0 order
94 # bearing in mind that CRFields.cr is a 64-bit SelectableInt. sigh.
99 initial_cr
= cr
.cr
.asint()
100 print("initial cr", bin(initial_cr
), bt
, ba
, bb
,
101 "tli", bin(imm
), lst
)
103 lst
= list(SVP64Asm(lst
, bigendian
))
104 e
= ExpectedState(pc
=4)
105 e
.crregs
[0] = crternlogi(bt
, ba
, bb
, imm
) << 3
106 e
.crregs
[1] = ba
<< 3
107 e
.crregs
[2] = bb
<< 3
108 self
.add_case(Program(lst
, bigendian
), initial_regs
=None, expected
=e
,
109 initial_cr
=initial_cr
)
111 def case_crternlogi_0(self
):
112 self
.do_case_crternlogi(0b1,
117 def case_crternlogi_random(self
):
119 imm
= hash_256(f
"crternlogi imm {i}") & 0xFF
120 bt
= hash_256(f
"crternlogi bt {i}") & 1
121 ba
= hash_256(f
"crternlogi ba {i}") & 1
122 bb
= hash_256(f
"crternlogi bb {i}") & 1
123 self
.do_case_crternlogi(bt
, ba
, bb
, imm
)
125 def do_case_crfternlogi(self
, bf
, bfa
, bfb
, imm
, mask
):
126 lst
= [f
"crfternlogi 3,4,5,%d,%d" % (imm
, mask
)]
135 initial_cr
= cr
.cr
.asint()
136 print("initial cr", bin(initial_cr
), bf
, bfa
, bfb
)
137 print("mask tli", bin(mask
), bin(imm
))
139 lst
= list(SVP64Asm(lst
, bigendian
))
140 e
= ExpectedState(pc
=4)
141 e
.crregs
[3] = crfternlogi(bf
, bfa
, bfb
, imm
, mask
)
144 self
.add_case(Program(lst
, bigendian
), initial_regs
=None, expected
=e
,
145 initial_cr
=initial_cr
)
147 def case_crfternlogi_0(self
):
148 self
.do_case_crfternlogi(0b1111,
153 def case_crfternlogi_random(self
):
155 imm
= hash_256(f
"crfternlogi imm {i}") & 0xFF
156 bf
= hash_256(f
"crfternlogi bf {i}") % 2 ** 4
157 bfa
= hash_256(f
"crfternlogi bfa {i}") % 2 ** 4
158 bfb
= hash_256(f
"crfternlogi bfb {i}") % 2 ** 4
159 msk
= hash_256(f
"crfternlogi msk {i}") % 2 ** 4
160 self
.do_case_crfternlogi(bf
, bfa
, bfb
, imm
, msk
)
162 def do_case_crfbinlog(self
, bf
, bfa
, bfb
, mask
):
163 lst
= ["crfbinlog 3,4,5,%d" % mask
]
173 initial_cr
= cr
.cr
.asint()
174 print("initial cr", bin(initial_cr
), bf
, bfa
, bfb
)
175 print("mask lut2", bin(mask
), bin(lut
))
177 lst
= list(SVP64Asm(lst
, bigendian
))
178 e
= ExpectedState(pc
=4)
179 e
.crregs
[3] = crfbinlog(bf
, bfa
, bfb
, mask
)
182 self
.add_case(Program(lst
, bigendian
), initial_regs
=None, expected
=e
,
183 initial_cr
=initial_cr
)
185 def case_crfbinlog_0(self
):
186 self
.do_case_crfbinlog(0b1111,
190 def case_crfbinlog_random(self
):
192 bf
= hash_256(f
"crfbinlog bf {i}") % 2 ** 4
193 bfa
= hash_256(f
"crfbinlog bfa {i}") % 2 ** 4
194 bfb
= hash_256(f
"crfbinlog bfb {i}") % 2 ** 4
195 msk
= hash_256(f
"crfbinlog msk {i}") % 2 ** 4
196 self
.do_case_crfbinlog(bf
, bfa
, bfb
, msk
)
198 def do_case_ternlogi(self
, rc
, rt
, ra
, rb
, imm
):
199 rc_dot
= "." if rc
else ""
200 lst
= [f
"ternlogi{rc_dot} 3, 4, 5, {imm}"]
201 initial_regs
= [0] * 32
208 lst
= list(SVP64Asm(lst
, bigendian
))
209 e
= ExpectedState(pc
=4)
219 if imm
& 2 ** lut_index
:
221 e
.intregs
[3] = expected
225 if expected
& 2 ** 63: # sign extend
230 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
231 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
233 def do_case_binlog(self
, ra
, rb
, rc
, nh
):
234 lst
= ["binlog 3, 4, 5, 6, %d" % nh
]
235 initial_regs
= [0] * 32
239 lut
= rc
& 0b11111111 # one of two 4-bit LUTs is in 1st 8 bits
240 if nh
== 1: # top half (bits 4-7... sigh MSB 56-59) else 0-3 (60-63)
243 lst
= list(SVP64Asm(lst
, bigendian
))
244 e
= ExpectedState(pc
=4)
252 if lut
& 2 ** lut_index
:
254 e
.intregs
[3] = expected
258 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
260 def case_binlog_0(self
):
261 self
.do_case_binlog(0x8000_0000_FFFF_0000,
262 0x8000_0000_FF00_FF00,
264 self
.do_case_binlog(0x8000_0000_FFFF_0000,
265 0x8000_0000_FF00_FF00,
268 def case_binlog_random(self
):
270 ra
= hash_256(f
"binlog ra {i}") % 2 ** 64
271 rb
= hash_256(f
"binlog rb {i}") % 2 ** 64
272 rc
= hash_256(f
"binlog rc {i}") % 2 ** 8
273 nh
= hash_256(f
"binlog nh {i}") & 0b1
274 self
.do_case_binlog(ra
, rb
, rc
, nh
)
276 def do_case_grev(self
, w
, is_imm
, ra
, rb
):
277 bits
= 32 if w
else 64
278 masked_rb
= rb
% bits
280 lst
= [f
"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
282 lst
= [f
"grev{'w' if w else ''}. 3, 4, 5"]
283 initial_regs
= [0] * 32
288 lst
= list(SVP64Asm(lst
, bigendian
))
289 e
= ExpectedState(pc
=4)
291 for i
in range(bits
):
292 dest_bit
= i ^ masked_rb
294 expected |
= 2 ** dest_bit
295 e
.intregs
[3] = expected
298 if expected
& 2 ** 63: # sign extend
303 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
304 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
306 def case_ternlogi_0(self
):
307 self
.do_case_ternlogi(False,
308 0x8000_0000_FFFF_0000,
309 0x8000_0000_FF00_FF00,
310 0x8000_0000_F0F0_F0F0, 0x80)
311 self
.do_case_ternlogi(True,
312 0x8000_0000_FFFF_0000,
313 0x8000_0000_FF00_FF00,
314 0x8000_0000_F0F0_F0F0, 0x80)
316 def case_ternlogi_FF(self
):
317 self
.do_case_ternlogi(False, 0, 0, 0, 0xFF)
318 self
.do_case_ternlogi(True, 0, 0, 0, 0xFF)
320 def case_ternlogi_random(self
):
322 rc
= bool(hash_256(f
"ternlogi rc {i}") & 1)
323 imm
= hash_256(f
"ternlogi imm {i}") & 0xFF
324 rt
= hash_256(f
"ternlogi rt {i}") % 2 ** 64
325 ra
= hash_256(f
"ternlogi ra {i}") % 2 ** 64
326 rb
= hash_256(f
"ternlogi rb {i}") % 2 ** 64
327 self
.do_case_ternlogi(rc
, rt
, ra
, rb
, imm
)
329 @skip_case("grev removed -- leaving code for later use in grevlut")
330 def case_grev_random(self
):
332 w
= hash_256(f
"grev w {i}") & 1
333 is_imm
= hash_256(f
"grev is_imm {i}") & 1
334 ra
= hash_256(f
"grev ra {i}") % 2 ** 64
335 rb
= hash_256(f
"grev rb {i}") % 2 ** 64
336 self
.do_case_grev(w
, is_imm
, ra
, rb
)
338 @skip_case("grev removed -- leaving code for later use in grevlut")
339 def case_grevi_1(self
):
340 self
.do_case_grev(False, True, 14361919363078703450,
343 @skip_case("grev removed -- leaving code for later use in grevlut")
344 def case_grevi_2(self
):
345 self
.do_case_grev(True, True, 397097147229333315, 8326716970539357702)
347 @skip_case("grev removed -- leaving code for later use in grevlut")
348 def case_grevi_3(self
):
349 self
.do_case_grev(True, True, 0xFFFF_FFFF_0000_0000, 6)
351 def case_byterev(self
):
353 options
= (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
354 values
= (0x0123456789ABCDEF, 0xFEDCBA9876543210)
355 for RS
, (pack_str
, mnemonic
) in itertools
.product(values
, options
):
356 prog
= Program(list(SVP64Asm(["%s 3,4" % mnemonic
])), bigendian
)
357 chunks
= struct
.unpack("<" + pack_str
, struct
.pack("<Q", RS
))
358 res
= struct
.unpack("<Q", struct
.pack(">" + pack_str
, *chunks
))[0]
359 with self
.subTest(mnemonic
=mnemonic
, RS
=hex(RS
), expected
=hex(res
)):
362 e
= ExpectedState(pc
=4, int_regs
=gprs
)
364 self
.add_case(prog
, gprs
, expected
=e
)
366 def case_sv_byterev(self
):
367 """ sv.brh/brw/brd """
368 options
= (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
370 for idx
, (pack_str
, mnemonic
) in itertools
.product(values
, options
):
371 listing
= list(SVP64Asm(["sv.%s *10,*20" % mnemonic
]))
372 prog
= Program(listing
, bigendian
)
374 svstate
= SVP64State()
378 for elidx
in range(VL
):
379 k
= "sv.%s %d %d r20" % (mnemonic
, idx
, elidx
)
380 gprs
[20 + elidx
] = hash_256(k
) % 2**64
381 e
= ExpectedState(pc
=8, int_regs
=gprs
)
382 for elidx
in range(VL
):
383 packed
= struct
.pack("<Q", gprs
[20 + elidx
])
384 chunks
= struct
.unpack( "<" + pack_str
, packed
)
385 packed
= struct
.pack(">" + pack_str
, *chunks
)
386 res
= struct
.unpack("<Q", packed
)[0]
387 e
.intregs
[10 + elidx
] = res
388 RS
= [hex(gprs
[20 + i
]) for i
in range(VL
)],
389 res
=[hex(e
.intregs
[10 + i
]) for i
in range(VL
)]
390 with self
.subTest(case_idx
=idx
, RS_in
=RS
, expected_RA
=res
):
391 self
.add_case(prog
, gprs
, expected
=e
, initial_svstate
=svstate
)
393 def do_case_sv_crternlogi(self
, idx
, bt
, ba
, bb
, imm
):
394 """note for now that this test is LIMITED due to the
395 range of CR EXTRA3 encoding, it can only do CR0 CR4 CR8 CR12 ... CR124
396 therefore BB is marked as *scalar*.
397 see https://bugs.libre-soc.org/show_bug.cgi?id=1034#c11
399 lst
= ["sv.crternlogi *0,*16,31,%d" % imm
]
400 # set up CR to match bt bit 0, ba bit 16, bb bit 31, in MSB0 order
401 # bearing in mind that CRFields.cr is a 64-bit SelectableInt. sigh.
403 #for i, (t, a, b) in enumerate(zip(bt, ba, bb)):
404 for i
, (t
, a
) in enumerate(zip(bt
, ba
)):
405 cr
.cr
[32+i
+0] = t
# *vector* BT
406 cr
.cr
[32+i
+16] = a
# *vector* BA
407 # XXX cannot do vector yet cr.cr[32+i+32] = bb # *SCALAR* BB
408 cr
.cr
[32+31] = bb
# *SCALAR* BB
409 initial_cr
= cr
.cr
.asint()
410 print("initial cr", bin(initial_cr
), bt
, ba
, bb
,
411 "tli", bin(imm
), lst
)
413 lst
= list(SVP64Asm(lst
, bigendian
))
414 e
= ExpectedState(pc
=8)
415 #for i, (t, a, b) in enumerate(zip(bt, ba, bb)):
416 for i
, (t
, a
) in enumerate(zip(bt
, ba
)):
417 k
,j
= i
>> 2, (3 - (i
% 4))
418 expected
= crternlogi(t
, a
, bb
, imm
) << j
419 e
.crregs
[k
+0] |
= expected
# vector result
420 e
.crregs
[k
+4] |
= a
<< j
# vector input BA
421 e
.crregs
[7] |
= bb
<< 3 # scalar input BB
422 with self
.subTest(case_idx
=idx
):
424 svstate
= SVP64State()
427 self
.add_case(Program(lst
, bigendian
), initial_regs
=None,
429 initial_cr
=initial_cr
,
430 initial_svstate
=svstate
)
432 def case_sv_crternlogi(self
):
434 bt
, ba
, bb
= [], [], []
436 t
= hash_256("crternlogi bt %d %d" % (i
, j
)) & 1
437 a
= hash_256("crternlogi ba %d %d" % (i
, j
)) & 1
438 b
= hash_256("crternlogi bb %d %d" % (i
, j
)) & 1
442 imm
= hash_256("crternlogi imm %d" % (i
)) & 0xFF
443 # temporarily do Vector BT, Vector BA, but *scalar* BB
444 self
.do_case_sv_crternlogi(i
, bt
, ba
, bb
[0], imm
)