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 class BitManipTestCase(TestAccumulatorBase
):
24 lst
= list(SVP64Asm(lst
, bigendian
))
25 initial_regs
= [0] * 32
26 initial_regs
[1] = 0x9231_5897_2083_ffff
27 e
= ExpectedState(pc
=4)
28 e
.intregs
[0] = bmatflip(initial_regs
[1])
29 e
.intregs
[1] = initial_regs
[1]
30 log("case_gbbd", bin(initial_regs
[1]), bin(e
.intregs
[0]))
31 log("hex", hex(initial_regs
[1]), hex(e
.intregs
[0]))
33 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
35 def do_case_crternlogi(self
, bf
, bfa
, bfb
, imm
, mask
):
36 lst
= [f
"crternlogi 3,4,5,%d,%d" % (imm
, mask
)]
45 initial_cr
= cr
.cr
.asint()
46 print("initial cr", bin(initial_cr
), bf
, bfa
, bfb
)
47 print("mask tli", bin(mask
), bin(imm
))
49 lst
= list(SVP64Asm(lst
, bigendian
))
50 e
= ExpectedState(pc
=4)
51 expected
= bf
&~mask
# start at BF, mask overwrites masked bits only
52 checks
= (bfb
, bfa
, bf
) # LUT positions 1<<0=bfb 1<<1=bfa 1<<2=bf
55 for j
, check
in enumerate(checks
):
58 maskbit
= (mask
>> i
) & 0b1
59 if (imm
& (1<<lut_index
)) and maskbit
:
61 e
.crregs
[3] = expected
64 self
.add_case(Program(lst
, bigendian
), initial_regs
=None, expected
=e
,
65 initial_cr
=initial_cr
)
67 def case_crternlogi_0(self
):
68 self
.do_case_crternlogi(0b1111,
73 def case_crternlogi_random(self
):
75 rc
= bool(hash_256(f
"crternlogi rc {i}") & 1)
76 imm
= hash_256(f
"crternlogi imm {i}") & 0xFF
77 bf
= hash_256(f
"crternlogi bf {i}") % 2 ** 4
78 bfa
= hash_256(f
"crternlogi bfa {i}") % 2 ** 4
79 bfb
= hash_256(f
"crternlogi bfb {i}") % 2 ** 4
80 msk
= hash_256(f
"crternlogi msk {i}") % 2 ** 4
81 self
.do_case_crternlogi(bf
, bfa
, bfb
, imm
, msk
)
83 def do_case_ternlogi(self
, rc
, rt
, ra
, rb
, imm
):
84 rc_dot
= "." if rc
else ""
85 lst
= [f
"ternlogi{rc_dot} 3, 4, 5, {imm}"]
86 initial_regs
= [0] * 32
93 lst
= list(SVP64Asm(lst
, bigendian
))
94 e
= ExpectedState(pc
=4)
104 if imm
& 2 ** lut_index
:
106 e
.intregs
[3] = expected
110 if expected
& 2 ** 63: # sign extend
115 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
116 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
118 def do_case_binlog(self
, ra
, rb
, rc
, nh
):
119 lst
= ["binlog 3, 4, 5, 6, %d" % nh
]
120 initial_regs
= [0] * 32
124 lut
= rc
& 0b11111111 # one of two 4-bit LUTs is in 1st 8 bits
125 if nh
== 1: # top half (bits 4-7... sigh MSB 56-59) else 0-3 (60-63)
128 lst
= list(SVP64Asm(lst
, bigendian
))
129 e
= ExpectedState(pc
=4)
137 if lut
& 2 ** lut_index
:
139 e
.intregs
[3] = expected
143 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
145 def case_binlog_0(self
):
146 self
.do_case_binlog(0x8000_0000_FFFF_0000,
147 0x8000_0000_FF00_FF00,
149 self
.do_case_binlog(0x8000_0000_FFFF_0000,
150 0x8000_0000_FF00_FF00,
153 def case_binlog_random(self
):
155 ra
= hash_256(f
"binlog ra {i}") % 2 ** 64
156 rb
= hash_256(f
"binlog rb {i}") % 2 ** 64
157 rc
= hash_256(f
"binlog rc {i}") % 2 ** 8
158 nh
= hash_256(f
"binlog nh {i}") & 0b1
159 self
.do_case_binlog(ra
, rb
, rc
, nh
)
161 def do_case_grev(self
, w
, is_imm
, ra
, rb
):
162 bits
= 32 if w
else 64
163 masked_rb
= rb
% bits
165 lst
= [f
"grev{'w' if w else ''}i. 3, 4, {masked_rb}"]
167 lst
= [f
"grev{'w' if w else ''}. 3, 4, 5"]
168 initial_regs
= [0] * 32
173 lst
= list(SVP64Asm(lst
, bigendian
))
174 e
= ExpectedState(pc
=4)
176 for i
in range(bits
):
177 dest_bit
= i ^ masked_rb
179 expected |
= 2 ** dest_bit
180 e
.intregs
[3] = expected
183 if expected
& 2 ** 63: # sign extend
188 e
.crregs
[0] = (eq
<< 1) |
(gt
<< 2) |
(lt
<< 3)
189 self
.add_case(Program(lst
, bigendian
), initial_regs
, expected
=e
)
191 def case_ternlogi_0(self
):
192 self
.do_case_ternlogi(False,
193 0x8000_0000_FFFF_0000,
194 0x8000_0000_FF00_FF00,
195 0x8000_0000_F0F0_F0F0, 0x80)
196 self
.do_case_ternlogi(True,
197 0x8000_0000_FFFF_0000,
198 0x8000_0000_FF00_FF00,
199 0x8000_0000_F0F0_F0F0, 0x80)
201 def case_ternlogi_FF(self
):
202 self
.do_case_ternlogi(False, 0, 0, 0, 0xFF)
203 self
.do_case_ternlogi(True, 0, 0, 0, 0xFF)
205 def case_ternlogi_random(self
):
207 rc
= bool(hash_256(f
"ternlogi rc {i}") & 1)
208 imm
= hash_256(f
"ternlogi imm {i}") & 0xFF
209 rt
= hash_256(f
"ternlogi rt {i}") % 2 ** 64
210 ra
= hash_256(f
"ternlogi ra {i}") % 2 ** 64
211 rb
= hash_256(f
"ternlogi rb {i}") % 2 ** 64
212 self
.do_case_ternlogi(rc
, rt
, ra
, rb
, imm
)
214 @skip_case("grev removed -- leaving code for later use in grevlut")
215 def case_grev_random(self
):
217 w
= hash_256(f
"grev w {i}") & 1
218 is_imm
= hash_256(f
"grev is_imm {i}") & 1
219 ra
= hash_256(f
"grev ra {i}") % 2 ** 64
220 rb
= hash_256(f
"grev rb {i}") % 2 ** 64
221 self
.do_case_grev(w
, is_imm
, ra
, rb
)
223 @skip_case("grev removed -- leaving code for later use in grevlut")
224 def case_grevi_1(self
):
225 self
.do_case_grev(False, True, 14361919363078703450,
228 @skip_case("grev removed -- leaving code for later use in grevlut")
229 def case_grevi_2(self
):
230 self
.do_case_grev(True, True, 397097147229333315, 8326716970539357702)
232 @skip_case("grev removed -- leaving code for later use in grevlut")
233 def case_grevi_3(self
):
234 self
.do_case_grev(True, True, 0xFFFF_FFFF_0000_0000, 6)
236 def case_byterev(self
):
238 options
= (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
239 values
= (0x0123456789ABCDEF, 0xFEDCBA9876543210)
240 for RS
, (pack_str
, mnemonic
) in itertools
.product(values
, options
):
241 prog
= Program(list(SVP64Asm(["%s 3,4" % mnemonic
])), bigendian
)
242 chunks
= struct
.unpack("<" + pack_str
, struct
.pack("<Q", RS
))
243 res
= struct
.unpack("<Q", struct
.pack(">" + pack_str
, *chunks
))[0]
244 with self
.subTest(mnemonic
=mnemonic
, RS
=hex(RS
), expected
=hex(res
)):
247 e
= ExpectedState(pc
=4, int_regs
=gprs
)
249 self
.add_case(prog
, gprs
, expected
=e
)
251 def case_sv_byterev(self
):
252 """ sv.brh/brw/brd """
253 options
= (("HHHH", "brh"), ("LL", "brw"), ("Q", "brd"))
255 for idx
, (pack_str
, mnemonic
) in itertools
.product(values
, options
):
256 listing
= list(SVP64Asm(["sv.%s *10,*20" % mnemonic
]))
257 prog
= Program(listing
, bigendian
)
259 svstate
= SVP64State()
263 for elidx
in range(VL
):
264 k
= "sv.%s %d %d r20" % (mnemonic
, idx
, elidx
)
265 gprs
[20 + elidx
] = hash_256(k
) % 2**64
266 e
= ExpectedState(pc
=8, int_regs
=gprs
)
267 for elidx
in range(VL
):
268 packed
= struct
.pack("<Q", gprs
[20 + elidx
])
269 chunks
= struct
.unpack( "<" + pack_str
, packed
)
270 packed
= struct
.pack(">" + pack_str
, *chunks
)
271 res
= struct
.unpack("<Q", packed
)[0]
272 e
.intregs
[10 + elidx
] = res
273 RS
= [hex(gprs
[20 + i
]) for i
in range(VL
)],
274 res
=[hex(e
.intregs
[10 + i
]) for i
in range(VL
)]
275 with self
.subTest(case_idx
=idx
, RS_in
=RS
, expected_RA
=res
):
276 self
.add_case(prog
, gprs
, expected
=e
, initial_svstate
=svstate
)