931ba7fba928aa904b64e5d9a3bca803bff0891b
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
)